package com.yanqu.road.server.manager.kuang.activity;

import com.yanqu.road.entity.config.system.PropertyWeightItem;
import com.yanqu.road.entity.enums.eGamePlayerEventType;
import com.yanqu.road.entity.enums.eMessageType;
import com.yanqu.road.entity.enums.kuang.eKuangAttributeType;
import com.yanqu.road.entity.enums.kuang.eKuangBattleLeaveType;
import com.yanqu.road.entity.enums.kuang.eKuangBattleNoticeType;
import com.yanqu.road.entity.enums.kuang.eKuangBattlePlaceType;
import com.yanqu.road.entity.kuang.battle.*;
import com.yanqu.road.entity.kuang.battle.helper.CrossKuangBattleAttackHelper;
import com.yanqu.road.entity.kuang.battle.helper.CrossKuangBattleNpcData;
import com.yanqu.road.entity.kuang.battle.helper.CrossKuangRankRewardHelper;
import com.yanqu.road.entity.kuang.config.KuangPlaceConfig;
import com.yanqu.road.entity.kuang.config.KuangSystemConfig;
import com.yanqu.road.entity.kuang.group.KuangMatchGroup;
import com.yanqu.road.entity.log.LogKuangBattleAttack;
import com.yanqu.road.entity.log.LogKuangBattlePlaceSeize;
import com.yanqu.road.entity.log.LogKuangBattleRank;
import com.yanqu.road.entity.player.CrossUserBaseInfo;
import com.yanqu.road.entity.player.UserBaseInfo;
import com.yanqu.road.logic.bussiness.kuang.KuangBusiness;
import com.yanqu.road.logic.config.GameConfig;
import com.yanqu.road.logic.pb.CrossKuangPb;
import com.yanqu.road.logic.pb.PlayerBasePb;
import com.yanqu.road.message.YanQuMessage;;
import com.yanqu.road.pb.kuang.Kuang;
import com.yanqu.road.pb.worldmessage.WorldMessageProto;
import com.yanqu.road.server.logic.MessageHelper;
import com.yanqu.road.server.manager.kuang.CrossKuangMgr;
import com.yanqu.road.server.manager.kuang.logic.CrossKuangChatLogic;
import com.yanqu.road.server.manager.log.CrossAutoLogMgr;
import com.yanqu.road.server.manager.user.CrossUserMgr;
import com.yanqu.road.server.protocol.ClientProtocol;
import com.yanqu.road.server.protocol.GameErrorCode;
import com.yanqu.road.server.protocol.GameProtocol;
import com.yanqu.road.server.protocol.Protocol;
import com.yanqu.road.utils.RandomHelper;
import com.yanqu.road.utils.YanQuMessageUtils;
import com.yanqu.road.utils.config.Config;
import com.yanqu.road.utils.date.DateHelper;
import com.yanqu.road.utils.property.Property;
import com.yanqu.road.utils.property.PropertyHelper;
import com.yanqu.road.utils.string.StringUtils;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * 矿场争夺战
 */
public class CrossKuangActivity extends CrossKuangBaseActivity {

    private RandomHelper randomHelper = new RandomHelper();

    /**
     * 当前轮次（开战第几天）
     */
    private int roundDay;

    /**
     * 活动总数据
     */
    private CrossKuangBattleData crossKuangBattleData;

    /**
     * 阵营宝库
     */
    private Map<Integer, CrossKuangTreasureData> treasureDataMap = new ConcurrentHashMap<>();

    /**
     * 阵营宝库公告
     */
    private Map<Integer, List<CrossKuangTreasureNoticeData>> treasureNoticeData = new ConcurrentHashMap<>();

    /**
     * 玩家战斗数据 => userId,玩家数据
     */
    private Map<Long, CrossKuangBattleUserData> userDataMap = new ConcurrentHashMap<>();

    /**
     * 阵营数据 => campId,阵营数据
     */
    private Map<Integer, CrossKuangBattleCampData> campDataMap = new ConcurrentHashMap<>();

    /**
     * 房间数据 => placeId,房间数据
     */
    private Map<Integer, CrossKuangBattlePlaceData> placeDataMap = new ConcurrentHashMap<>();

    /**
     * 宗门个人仙力榜单
     */
    private Map<Integer, CrossKuangRankListModel> campUserRankModelMap = new ConcurrentHashMap<>();

    /**
     * 个人战绩榜单
     */
    private CrossKuangRankListModel userScoreRankModel = new CrossKuangRankListModel();

    /**
     * 本轮宗门积分榜单
     */
    private CrossKuangRankListModel campScoreRankModel = new CrossKuangRankListModel();

    /**
     * 活动宗门积分榜单
     */
    private CrossKuangRankListModel campTotalScoreRankModel = new CrossKuangRankListModel();

    /**
     * 结算数据  轮次,记录
     */
    private Map<Integer, CrossKuangBattleEndRecord> endRecordMap = new ConcurrentHashMap<>();

    private CrossKuangChatLogic chatLogic;

    /**
     * 是否需要同步积分
     */
    private boolean needSyncCampScore = false;

    /**
     * 全服公告
     */
    private LinkedList<CrossKuangBattleNoticeData> noticeDataList = new LinkedList<>();

    /**
     * 宗门公告
     */
    private Map<Integer, LinkedList<CrossKuangBattleNoticeData>> campNoticeDataMap = new ConcurrentHashMap<>();

    /**
     * 攻击同步列表      placeId,List
     */
    private Map<Integer, List<CrossKuangBattleAttackHelper>> attackSyncListMap = new ConcurrentHashMap<>();

    private AtomicLong npcId = new AtomicLong(0);

    /**
     * npc攻击开关
     */
    private boolean npcAttack = true;

    /**
     * npc自动复活
     */
    private boolean npcRevive = true;

    /**
     * 玩家锁
     */
    private static final Map<Long, Object> playerLockMap = new ConcurrentHashMap<>();

    /**
     * 房间锁
     */
    private static final Map<Integer, Object> placeLockMap = new ConcurrentHashMap<>();


    /**
     * 内存房间玩家
     */
    private Map<Integer, Set<Long>> memUserMap = new HashMap<>();

    private Map<Long, CrossKuangBattleUserData> npcUserMap = new ConcurrentHashMap<>();

    private Map<Long, CrossKuangBattleNpcData> npcDataMap = new ConcurrentHashMap<>();

    private Set<Long> inBattleUserSet = new HashSet<>();

    /**
     * 游戏是否结束（某宗门分数达到最大）
     */
    private boolean battleEnd = false;

    /**
     * 获取玩家锁
     */
    private static Object getPlayerLock(long userId) {
        if (!playerLockMap.containsKey(userId)) {
            synchronized (playerLockMap) {
                if (!playerLockMap.containsKey(userId)) {
                    playerLockMap.put(userId, new Object());
                }
            }
        }
        return playerLockMap.get(userId);
    }


    /**
     * 获取房间锁
     */
    private static Object getPlaceLock(int placeId) {
        if (!placeLockMap.containsKey(placeId)) {
            synchronized (placeLockMap) {
                if (!placeLockMap.containsKey(placeId)) {
                    placeLockMap.put(placeId, new Object());
                }
            }
        }
        return placeLockMap.get(placeId);
    }


    private int weekId;

    private int groupId;


    public CrossKuangActivity(int _groupId) {
        // 加载配置
        reloadConfig();
        this.weekId = GameConfig.getSystemThisWeekId();
        this.groupId = _groupId;
        // 加载数据
        crossKuangBattleData = KuangBusiness.getCrossKuangBattleData(weekId, groupId);
        if (crossKuangBattleData == null) {
            // 初始化
            crossKuangBattleData = new CrossKuangBattleData();
            crossKuangBattleData.setWeekId(weekId);
            crossKuangBattleData.setGroupId(groupId);
            crossKuangBattleData.setRound(0);
            crossKuangBattleData.setRankReward(false);
            crossKuangBattleData.setCampScoreRecordMap(new ConcurrentHashMap<>());
            crossKuangBattleData.setUpdateTime(System.currentTimeMillis());
            crossKuangBattleData.setInsertOption();
        }
        roundDay = crossKuangBattleData.getRound();
        // 玩家信息
        userDataMap = KuangBusiness.getCrossKuangBattleUserDataMap(weekId, groupId);
        // 阵营信息
        campDataMap = KuangBusiness.getCrossKuangBattleCampDataMap(weekId, groupId);
        // 初始化阵营数据
        initCampData();
        // 宝地信息
        placeDataMap = KuangBusiness.getCrossKuangBattlePlaceDataMap(weekId, groupId);
        // 初始化宝地信息
        initPlaceData();
        // 最佳记录
        endRecordMap = KuangBusiness.getCrossKuangBattleEndRecordMap(weekId, groupId);

        // 阵营宝库
        treasureDataMap = KuangBusiness.getCrossKuangTreasureDataMap(weekId, groupId);
        // 初始化宝库数据
        initTreasureData();

        // 阵营公告数据
        treasureNoticeData = KuangBusiness.getCrossKuangTreasureNoticeDataMap(weekId, groupId);

        // 初始化榜单
        initAllRankList();

        // 聊天系统
        chatLogic = new CrossKuangChatLogic(groupId);
    }

    private void initTreasureData() {
        for (Integer campId : campDataMap.keySet()) {
            if (treasureDataMap.containsKey(campId)) {
                continue;
            }
            // 不存在则生成一个宝库
            CrossKuangTreasureData crossKuangTreasureData = new CrossKuangTreasureData();
            crossKuangTreasureData.setWeekId(weekId);
            crossKuangTreasureData.setGroupId(groupId);
            crossKuangTreasureData.setCampId(campId);
            crossKuangTreasureData.setRound(1);
            crossKuangTreasureData.setTreasureDetailDataMap(new ConcurrentHashMap<>());
            // 随机出大奖的位置
            crossKuangTreasureData.setSpecialPosition(randomHelper.next(1, 101));
            crossKuangTreasureData.setInsertOption();
            treasureDataMap.put(campId, crossKuangTreasureData);
        }
    }

    public int getTreasureDataByCmd(long userId) {
        int campId = getCampByUserId(userId);
        if (!treasureDataMap.containsKey(campId)) {
            return GameErrorCode.E_KUANG_PARAM_ERROR;
        }
        CrossKuangTreasureData treasureData = treasureDataMap.get(campId);
        Kuang.KuangGetTreasureRespMsg.Builder respMsg = Kuang.KuangGetTreasureRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setTreasureData(parseKuangTreasureDataTemp(treasureData));
        if (treasureNoticeData.containsKey(campId)) {
            List<CrossKuangTreasureNoticeData> list = new ArrayList<>(treasureNoticeData.get(campId));
            for (CrossKuangTreasureNoticeData noticeData : list) {
                Kuang.KuangTreasureNoticeDataTemp.Builder noticeDataTemp = parseKuangTreasureNoticeDataTemp(noticeData);
                if (noticeDataTemp != null) {
                    respMsg.addNoticeData(noticeDataTemp);
                }
            }
        }
        sendPacket(Protocol.U_KUANG_GET_TREASURE_DATA, respMsg, userId);
        return 0;
    }

    private Kuang.KuangTreasureDataTemp.Builder parseKuangTreasureDataTemp(CrossKuangTreasureData treasureData) {
        if (treasureData == null) {
            return null;
        }
        Kuang.KuangTreasureDataTemp.Builder builder = Kuang.KuangTreasureDataTemp.newBuilder();
        builder.setCampId(treasureData.getCampId());
        builder.setRound(treasureData.getRound());
        for (CrossKuangTreasureDetailData detailData : treasureData.getTreasureDetailDataMap().values()) {
            Kuang.KuangTreasureDetailDataTemp.Builder detailDataTemp = parseKuangTreasureDetailDataTemp(detailData);
            if (detailDataTemp != null) {
                builder.addDetail(detailDataTemp);
            }
        }
        return builder;
    }

    private Kuang.KuangTreasureDetailDataTemp.Builder parseKuangTreasureDetailDataTemp(CrossKuangTreasureDetailData detailData) {
        if (detailData == null) {
            return null;
        }
        Kuang.KuangTreasureDetailDataTemp.Builder builder = Kuang.KuangTreasureDetailDataTemp.newBuilder();
        builder.setPosition(detailData.getPosition());
        builder.setReward(detailData.getReward());
        builder.setUserId(detailData.getUserId());
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(detailData.getUserId());
        if (userBaseInfo == null) {
            return null;
        }
        builder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        builder.setOpenTime(detailData.getOpenTime());
        builder.setIsSpecial(detailData.isSpecial());
        return builder;
    }

    private Kuang.KuangTreasureNoticeDataTemp.Builder parseKuangTreasureNoticeDataTemp(CrossKuangTreasureNoticeData treasureNoticeData) {
        if (treasureNoticeData == null) {
            return null;
        }
        Kuang.KuangTreasureNoticeDataTemp.Builder builder = Kuang.KuangTreasureNoticeDataTemp.newBuilder();
        builder.setRound(treasureNoticeData.getRound());
        builder.setReward(treasureNoticeData.getReward());
        builder.setUserBaseInfo(PlayerBasePb.parsePlayerBaseTempMsg(treasureNoticeData.getUserBaseInfo()));
        builder.setOpenTime(treasureNoticeData.getOpenTime());
        return builder;
    }

    /**
     * 选择宝物
     * @param userId
     * @param position
     * @return
     */
    public int chooseTreasureByCmd(long userId, int position) {
        int campId = getCampByUserId(userId);
        if (!treasureDataMap.containsKey(campId)) {
            return GameErrorCode.E_KUANG_PARAM_ERROR;
        }
        KuangSystemConfig kuangSystemConfig = config.getKuangSystemConfig();
        if (kuangSystemConfig == null) {
            return GameErrorCode.E_KUANG_CONFIG_NOT_FOUND;
        }
        KuangMatchGroup matchGroup = CrossKuangMgr.getMatchGroup(weekId, groupId);
        if (matchGroup == null) {
            return GameErrorCode.E_KUANG_SYSTEM_NOT_OPEN;
        }
        CrossKuangTreasureData treasureData = null;
        CrossKuangTreasureDetailData detailData = null;
        synchronized (treasureDataMap) {
            treasureData = treasureDataMap.get(campId);
            if (treasureData == null) {
                return GameErrorCode.E_KUANG_PARAM_ERROR;
            }
            if (treasureData.getTreasureDetailDataMap().containsKey(position)) {
                return GameErrorCode.E_KUANG_PARAM_ERROR;
            }
            if (position < 1 || position > kuangSystemConfig.getLotteryBoxNum()) {
                return GameErrorCode.E_KUANG_PARAM_ERROR;
            }
            // 判断是否为大奖
            Property reward = new Property();
            boolean isSpecial = false;
            if (position == treasureData.getSpecialPosition()) {
                // 抽中大奖
                reward = getPropertyWeightItem(kuangSystemConfig.getLotterySpecialReward(matchGroup.getOpenDay()));
                isSpecial = true;
            } else {
                // 普通奖励
                reward = getPropertyWeightItem(kuangSystemConfig.getLotteryGeneraReward(matchGroup.getOpenDay()));
            }
            detailData = new CrossKuangTreasureDetailData();
            detailData.setPosition(position);
            detailData.setReward(PropertyHelper.parsePropertyToString(reward));
            detailData.setUserId(userId);
            detailData.setOpenTime(System.currentTimeMillis());
            detailData.setSpecial(isSpecial);
            treasureData.getTreasureDetailDataMap().put(position, detailData);
            treasureData.setUpdateOption();
            // 抽中大奖后重置
            if (isSpecial) {
                // 加公告
                CrossKuangTreasureNoticeData treasureNoticeData = new CrossKuangTreasureNoticeData();
                treasureNoticeData.setWeekId(treasureData.getWeekId());
                treasureNoticeData.setGroupId(treasureData.getGroupId());
                treasureNoticeData.setRound(treasureData.getRound());
                treasureNoticeData.setCampId(campId);
                treasureNoticeData.setUserId(userId);
                treasureNoticeData.setUserBaseInfo(CrossUserMgr.getUserBaseInfo(userId));
                treasureNoticeData.setReward(PropertyHelper.parsePropertyToString(reward));
                treasureNoticeData.setOpenTime(System.currentTimeMillis());
                treasureNoticeData.setInsertOption();
                addTreasureNoticeData(treasureNoticeData);

                // 开始重置
                treasureData.setRound(treasureData.getRound() + 1);
                treasureData.setTreasureDetailDataMap(new ConcurrentHashMap<>());
                // 随机出大奖的位置
                treasureData.setSpecialPosition(randomHelper.next(1, 101));
            }
        }
        // 回到游戏服
        Kuang.CrossKuangChooseTreasureRespMsg.Builder respMsg = Kuang.CrossKuangChooseTreasureRespMsg.newBuilder();
        respMsg.setRet(0);
        Kuang.KuangTreasureDetailDataTemp.Builder detailDataTemp = parseKuangTreasureDetailDataTemp(detailData);
        if (detailDataTemp != null) {
            respMsg.setDetail(detailDataTemp);
        }
        Kuang.KuangTreasureDataTemp.Builder treasureDataTemp = parseKuangTreasureDataTemp(treasureData);
        if (treasureDataTemp != null) {
            respMsg.setTreasureData(treasureDataTemp);
        }
        sendPacket(GameProtocol.S_KUANG_CHOOSE_TREASURE_FROM_CROSS, respMsg, userId);
        // 同步宝库开启信息
        syncTreasureDataToAllCampMember(campId, treasureData, detailData);
        return 0;
    }

    public Property getPropertyWeightItem(List<PropertyWeightItem> list){
        Property reward = new Property();
        int sumWeight = 0;
        for (PropertyWeightItem item : list) {
            sumWeight += item.getWeight();
        }
        int num = randomHelper.next(0, sumWeight);
        for (PropertyWeightItem config : list) {
            int weight = config.getWeight();
            if (num < weight) {
                reward = config.getProperty();
                break;
            }
            num -= weight;
        }
        return reward;
    }

    public void addTreasureNoticeData(CrossKuangTreasureNoticeData noticeData) {
        if (noticeData == null) {
            return;
        }
        synchronized (treasureNoticeData) {
            List<CrossKuangTreasureNoticeData> list = treasureNoticeData.getOrDefault(noticeData.getCampId(), new ArrayList<>());
            list.add(noticeData);
            treasureNoticeData.put(noticeData.getCampId(), list);
        }
        syncTreasureNoticeDataToAllCampMember(noticeData.getCampId(), noticeData);
    }

    /**
     * 同步宝库信息到本宗门的成员
     */
    public void syncTreasureDataToAllCampMember(int campId, CrossKuangTreasureData treasureData, CrossKuangTreasureDetailData detailData) {
        if (treasureData == null || detailData == null) {
            return;
        }
        CrossKuangBattleCampData campData = getCampData(campId);
        if (campData == null) {
            return;
        }
        Kuang.KuangTreasureSyncMsg.Builder builder = Kuang.KuangTreasureSyncMsg.newBuilder();
        builder.setDetail(parseKuangTreasureDetailDataTemp(detailData));
        builder.setTreasureData(parseKuangTreasureDataTemp(treasureData));
        Set<Long> list = getUserIdListInActivityByCampId(campId);
        sendPacketToAll(weekId, groupId, Protocol.U_KUANG_TREASURE_SYNC, builder, list);
    }


    /**
     * 同步宝库公告到本宗门的成员
     */
    public void syncTreasureNoticeDataToAllCampMember(int campId, CrossKuangTreasureNoticeData treasureNoticeData) {
        if (treasureNoticeData == null) {
            return;
        }
        CrossKuangBattleCampData campData = getCampData(campId);
        if (campData == null) {
            return;
        }
        Kuang.KuangTreasureNoticeSyncMsg.Builder builder = Kuang.KuangTreasureNoticeSyncMsg.newBuilder();
        builder.setNoticeData(parseKuangTreasureNoticeDataTemp(treasureNoticeData));
        Set<Long> list = getUserIdListInActivityByCampId(campId);
        sendPacketToAll(weekId, groupId, Protocol.U_KUANG_TREASURE_NOTICE_SYNC, builder, list);
    }

    /**
     * 初始化榜单
     */
    private void initAllRankList() {
        Map<Integer, CrossKuangRankListModel> campUserRankModelMap = new ConcurrentHashMap<>();
        CrossKuangRankListModel userScoreRankModel = new CrossKuangRankListModel();
        for (CrossKuangBattleUserData userData : userDataMap.values()) {
            // 宗门仙力排行榜
            CrossKuangRank rank = new CrossKuangRank(String.valueOf(userData.getUserId()), userData.getAttributeMap().getOrDefault(eKuangAttributeType.AttributeEnum_Ability, 0L), userData.getUpdatePropertyTime());
            campUserRankModelMap.putIfAbsent(userData.getCampId(), new CrossKuangRankListModel());
            campUserRankModelMap.get(userData.getCampId()).rankChange(rank);
            // 个人战绩排行
            long totalScore = userData.calcTotalScore();
            if (totalScore > 0) {
                userScoreRankModel.rankChange(new CrossKuangRank(String.valueOf(userData.getUserId()), totalScore, userData.getUpdateScoreTime()));
            }
        }
        CrossKuangRankListModel campScoreRankModel = new CrossKuangRankListModel();
        CrossKuangRankListModel campTotalScoreRankModel = new CrossKuangRankListModel();
        for (CrossKuangBattleCampData campData : campDataMap.values()) {
            campScoreRankModel.rankChange(new CrossKuangRank(String.valueOf(campData.getCampId()), campData.getScore(), campData.getUpdateScoreTime()));
            // 活动总积分
            campTotalScoreRankModel.rankChange(new CrossKuangRank(String.valueOf(campData.getCampId()), campData.getTotalScore(), campData.getUpdateScoreTime()));
        }
        this.campUserRankModelMap = campUserRankModelMap;
        this.campScoreRankModel = campScoreRankModel;
        this.userScoreRankModel = userScoreRankModel;
        this.campTotalScoreRankModel = campTotalScoreRankModel;
    }

    /**
     * 初始化阵营数据
     */
    private void initCampData() {
        KuangMatchGroup matchGroup = CrossKuangMgr.getMatchGroup(weekId, groupId);
        if (matchGroup == null) {
            return;
        }
        List<Long> serverIdList = new ArrayList<>(matchGroup.getServerIdList());
        Collections.shuffle(serverIdList);
        for (int campId = 1; campId <= 4; campId++) {
            if (!campDataMap.containsKey(campId)) {
                CrossKuangBattleCampData campData = new CrossKuangBattleCampData();
                campData.setWeekId(weekId);
                campData.setGroupId(groupId);
                campData.setCampId(campId);
                campData.setServerIdList(new HashSet<>());
                // 分配一下阵营
                for (int i = 0; i < serverIdList.size(); i++) {
                    if ((i % 4) + 1 == campId) {
                        campData.getServerIdList().add(serverIdList.get(i));
                    }
                }
                campData.setScore(0);
                campData.setTotalScore(0);
                campData.setInsertOption();
                campDataMap.put(campId, campData);
            }
        }
    }

    public int getChatByCmd(long userId, List<Integer> paramList) {
        if (paramList.isEmpty()) {
            return GameErrorCode.E_KUANG_PARAM_ERROR;
        }
        List<WorldMessageProto.WorldMessageTempMsg> dataList = new ArrayList<>();
        for (int range : paramList) {
            int id = 0;
            if (range == CrossKuangChatLogic.RANGE_ALL) {
                id = groupId;
            } else if (range == CrossKuangChatLogic.RANGE_CAMP) {
                id = getCampByUserId(userId);
            }

            if (range <= 0 || id <= 0) {
                continue;
            }
            dataList.addAll(chatLogic.getChatMsg(range, id));
        }
        Kuang.CrossKuangChatListRespMsg.Builder respMsg = Kuang.CrossKuangChatListRespMsg.newBuilder();
        if (dataList.size() > 0) {
            dataList.sort(Comparator.comparingLong(WorldMessageProto.WorldMessageTempMsg::getSendTime));
            WorldMessageProto.WorldMessageListMsg.Builder worldMessageListMsg = WorldMessageProto.WorldMessageListMsg.newBuilder();
            worldMessageListMsg.addAllDataList(dataList);
            respMsg.setDataList(worldMessageListMsg);
        }
        sendPacket(Protocol.U_KUANG_CHAT_LIST, respMsg, userId);
        return 0;
    }

    public int sendChatByCmd(long userId, WorldMessageProto.WorldMessageTempMsg.Builder worldMessageTemp) {
        int range = 0;
        int id = 0;
        if (eMessageType.KuangPublicChat.getValue() == worldMessageTemp.getType()) {
            range = CrossKuangChatLogic.RANGE_ALL;
            id = groupId;
            // 公屏聊天加上阵营
            worldMessageTemp.setExtraParams(String.valueOf(getCampByUserId(userId)));
        } else if (eMessageType.KuangCampChat.getValue() == worldMessageTemp.getType()) {
            range = CrossKuangChatLogic.RANGE_CAMP;
            id = getCampByUserId(userId);
        }

        if (range <= 0 || id <= 0) {
            return 0;
        }
        chatLogic.chat(range, id, 1, worldMessageTemp.build());
        return 0;
    }


    public void syncChat(int range, int id, WorldMessageProto.WorldMessageTempMsg chatMsg) {
        KuangMatchGroup matchGroup = CrossKuangMgr.getMatchGroup(weekId, groupId);
        if (matchGroup == null) {
            return;
        }
        List<Long> userIdList = new ArrayList<>();
        if (range == CrossKuangChatLogic.RANGE_ALL) {
            // 所有人都要接收，所以换个发包方式
            YanQuMessage pbMsg = YanQuMessageUtils.buildMessage(Protocol.A_WORLD_MESSAGE_TRANSFER, chatMsg);
            for (long serverId : matchGroup.getServerIdList()) {
                MessageHelper.sendPacket(serverId, 0, pbMsg);
            }
            return;
        } else if (range == CrossKuangChatLogic.RANGE_CAMP) {
            userIdList = userDataMap.values().stream().filter(item -> item.getCampId() == id).mapToLong(CrossKuangBattleUserData::getUserId).boxed().collect(Collectors.toList());
        }
        if (!userIdList.isEmpty()) {
            sendPacketToAll(weekId, groupId, ClientProtocol.U_WORLD_MESSAGE_SYNC, chatMsg.toBuilder(), userIdList);
        }
    }


    /**
     * 初始化宝地信息
     */
    private void initPlaceData() {
        for (KuangPlaceConfig placeConfig : config.getPlaceConfigMap().values()) {
            if (placeConfig == null) {
                continue;
            }
            int placeId = placeConfig.getId();
            synchronized (getPlaceLock(placeId)) {
                if (!placeDataMap.containsKey(placeId)) {
                    CrossKuangBattlePlaceData placeData = new CrossKuangBattlePlaceData();
                    placeData.setWeekId(weekId);
                    placeData.setGroupId(groupId);
                    placeData.setPlaceId(placeId);
                    // 初始化阵营占领数据
                    Map<Integer, CrossKuangBattlePlaceSeizeInfo> seizeInfoMap = new ConcurrentHashMap<>();
                    for (int campId : campDataMap.keySet()) {
                        seizeInfoMap.put(campId, new CrossKuangBattlePlaceSeizeInfo(campId));
                    }
                    // 固定占领
                    if (placeConfig.getType() != eKuangBattlePlaceType.Place.getValue()) {
                        // 宗门
                        placeData.setCampId(placeId);
                    }
                    placeData.setSeizeInfoMap(seizeInfoMap);
                    long nowTime = System.currentTimeMillis();
                    placeData.setUpdateTime(nowTime);
                    placeData.setSeizeTime(nowTime);
                    placeData.setLastSeizeRewardTime(nowTime);
                    placeData.setLastNoticeSeizeTime(nowTime);
                    placeData.setInsertOption();
                    placeDataMap.put(placeId, placeData);
                }
            }
        }
    }

    /**
     * 活动是否战斗中【开战首日、次日战斗开始时间，开战首日、次日战斗结束时间】
     */
    public boolean isBattleTime() {
        if (config == null) {
            return false;
        }
        if (battleEnd) {
            return false;
        }
        return config.isBattleTime(crossKuangBattleData.getRound());
    }

    /**
     * 活动是否开启 【开战首日、次日战斗开始准备时间，开战首日、次日战斗结束时间】
     */
    public boolean isOpenTime() {
        if (config == null) {
            return false;
        }
        return config.isOpenTime(crossKuangBattleData.getRound());
    }

    public void save() {
        // 保存活动数据
        if (crossKuangBattleData != null) {
            if (crossKuangBattleData.isInsertOption()) {
                KuangBusiness.addCrossKuangBattleData(crossKuangBattleData);
            } else if (crossKuangBattleData.isUpdateOption()) {
                KuangBusiness.updateCrossKuangBattleData(crossKuangBattleData);
            }
        }
        // 保存用户数据
        for (CrossKuangBattleUserData userData : userDataMap.values()) {
            if (userData.isInsertOption()) {
                KuangBusiness.addCrossKuangBattleUserData(userData);
            } else if (userData.isUpdateOption()) {
                KuangBusiness.updateCrossKuangBattleUserData(userData);
            }
        }
        // 保存宗门数据
        for (CrossKuangBattleCampData campData : campDataMap.values()) {
            if (campData.isInsertOption()) {
                KuangBusiness.addCrossKuangBattleCampData(campData);
            } else if (campData.isUpdateOption()) {
                KuangBusiness.updateCrossKuangBattleCampData(campData);
            }
        }
        // 保存宝地信息
        for (CrossKuangBattlePlaceData placeData : placeDataMap.values()) {
            if (placeData.isInsertOption()) {
                KuangBusiness.addCrossKuangBattlePlaceData(placeData);
            } else if (placeData.isUpdateOption()) {
                KuangBusiness.updateCrossKuangBattlePlaceData(placeData);
            }
        }
        // 战绩
        for (CrossKuangBattleEndRecord endRecord : endRecordMap.values()) {
            if (endRecord.isInsertOption()) {
                KuangBusiness.addCrossKuangBattleEndRecord(endRecord);
            } else if (endRecord.isUpdateOption()) {
                KuangBusiness.updateCrossKuangBattleEndRecord(endRecord);
            }
        }
        for (CrossKuangTreasureData treasureData : treasureDataMap.values()) {
            if (treasureData.isInsertOption()) {
                KuangBusiness.addCrossKuangTreasureData(treasureData);
            } else if (treasureData.isUpdateOption()) {
                KuangBusiness.updateCrossKuangTreasureData(treasureData);
            }
        }
        for (List<CrossKuangTreasureNoticeData> list : treasureNoticeData.values()) {
            for (int i = 0; i < list.size(); i++) {
                CrossKuangTreasureNoticeData noticeData = list.get(i);
                if (noticeData.isInsertOption()) {
                    KuangBusiness.addCrossKuangTreasureNoticeData(noticeData);
                }
            }
        }
        // 日志
//        CrossKuangLog.save();
    }

    /**
     * 所有宗门最高积分
     */
    public long getCampMaxScore() {
        long score = 0;
        List<CrossKuangBattleCampData> list = new ArrayList<>(campDataMap.values());
        for (CrossKuangBattleCampData campData : list) {
            score = Math.max(campData.getScore(), score);
        }
        return score;
    }


    /**
     * 获取宝地信息
     *
     * @param placeId 宝地id
     */
    private CrossKuangBattlePlaceData getPlaceData(int placeId) {
        return placeDataMap.get(placeId);
    }

    private void addMemUser(int placeId, long userId) {
        synchronized (memUserMap) {
            Set<Long> userSet = memUserMap.getOrDefault(placeId, new HashSet<>());
            userSet.add(userId);
            memUserMap.put(placeId, userSet);
        }
    }

    private void removeMemUser(int placeId, long userId) {
        synchronized (memUserMap) {
            Set<Long> userSet = memUserMap.getOrDefault(placeId, new HashSet<>());
            userSet.remove(userId);
            memUserMap.put(placeId, userSet);
        }
    }

    private Set<Long> getMemUserList(int placeId) {
        return new HashSet<>(memUserMap.getOrDefault(placeId, new HashSet<>()));
    }

    private boolean isNpc(long userId) {
        return npcUserMap.containsKey(userId) && npcDataMap.containsKey(userId);
    }

    /**
     * 初始化用户数据
     */
    private CrossKuangBattleUserData getUserData(long userId) {
        if (userId == 0) {
            return null;
        }
        if (isNpc(userId)) {
            return npcUserMap.get(userId);
        }
        return userDataMap.get(userId);
    }

    private CrossKuangBattleUserData initUserData(long userId) {
        return initUserData(userId, new ConcurrentHashMap<>());
    }

    private CrossKuangBattleUserData initUserData(long userId, Map<eKuangAttributeType, Long> attributeMap) {
        synchronized (getPlayerLock(userId)) {
            if (!userDataMap.containsKey(userId)) {
                long serverId = CrossUserMgr.getServerIdByUserId(userId);
                // 宗门id
                int campId = getCampIdByServerId(serverId);
                if (campId == 0) {
                    return null;
                }
                long nowTime = System.currentTimeMillis();
                CrossKuangBattleUserData userData = new CrossKuangBattleUserData();
                userData.setWeekId(weekId);
                userData.setGroupId(groupId);
                userData.setUserId(userId);
                userData.setServerId(serverId);
                // 宗门id
                userData.setCampId(campId);
                // 出生地id
                userData.setPlaceId(0);
                // 可传送时间
                userData.setTransferTime(nowTime);
                // 可复活时间
                userData.setReviveTime(nowTime);
                // 复活次数
                userData.setReviveCnt(0);
                // 更新下属性
                updateProperty(userData, attributeMap);
                userData.setInsertOption();
                userDataMap.put(userId, userData);
            }
        }
        return userDataMap.get(userId);
    }

    /**
     * 宗门人数是否达到上限
     */
    public boolean checkCampPlayerLimit(int campId, int placeId) {
        KuangPlaceConfig placeConfig = config.getPlaceConfigMap().get(placeId);
        // 出生点不做拦截，无上限
        if (placeConfig.getType() != eKuangBattlePlaceType.Place.getValue()) {
            return false;
        }
        int cnt = 0;
        for (Long userId : getMemUserList(placeId)) {
            CrossKuangBattleUserData userData = getUserData(userId);
            if (userData == null || userData.getUserState() == 1) {
                continue;
            }
            if (campId == userData.getCampId()) {
                cnt++;
            }
        }
        // 单房间人数上限
        return cnt >= GameConfig.KUANG_PVP_ROOM_PEOPLE_NUM_MAX;
    }

    /**
     * 加入到房间中
     *
     * @param placeId  宝地id
     * @param userData 用户数据
     */
    private void joinPlace(int placeId, CrossKuangBattleUserData userData) {
        if (userData == null) {
            return;
        }
        long userId = userData.getUserId();
        // placeId  = 0 为空房间
        if (placeId != 0) {
            synchronized (getPlaceLock(placeId)) {
                // 当前宝地宗门人数
                if (checkCampPlayerLimit(userData.getCampId(), placeId)) {
                    return;
                }
                // 加入到新房间
                addMemUser(placeId, userId);
                // 检测占领时间
                checkPlaceSeizeTime(placeId, true);
            }
        }
        userData.setPlaceId(placeId);
        if (placeId != 0) {
            CrossKuangBattlePosition position = userData.getPosition();
            // 随机位置
            // 获取玩家的头像半径
            int radius = config.getProfileRadius(userData.getBattleRecord().getKill());
            // 房间半径
            KuangPlaceConfig placeConfig = config.getPlaceConfigMap().get(placeId);
            int placeRadius = placeConfig.getRadius();
            // 玩家位置半径
            int positionRadius = 0;
            if (radius > placeRadius) {
                positionRadius = placeRadius;
            } else {
                positionRadius = placeRadius - radius;
            }
            // 回复活点随机圆内位置
            if (placeConfig.getType() != eKuangBattlePlaceType.Place.getValue() || isNpc(userId)) {
                positionRadius = randomHelper.next(0, positionRadius + 1);
            }
            // 随机一个角度
            int angdeg = randomHelper.next(0, 360);
            double x1 = 600 + positionRadius * Math.cos(Math.toRadians(angdeg));
            double y1 = 900 + positionRadius * Math.sin(Math.toRadians(angdeg));
            position.setX(String.valueOf(x1));
            position.setY(String.valueOf(y1));
            position.setDirX("0");
            position.setDirY("0");
            position.setTime(System.currentTimeMillis());
            // 通知
            Kuang.KuangBattleEnterPlaceSync.Builder syncMsg = Kuang.KuangBattleEnterPlaceSync.newBuilder();
            syncMsg.setUser(parseKuangBattleOtherUserTemp(userData));
            sendPacketToAll(weekId, groupId, Protocol.U_KUANG_ENTER_PLACE_SYNC, syncMsg, getMemUserList(placeId));
        }
    }

    /**
     * 离开房间
     */
    public void leavePlace(CrossKuangBattleUserData userData, eKuangBattleLeaveType type) {
        if (userData == null) {
            return;
        }
        long userId = userData.getUserId();
        int placeId = userData.getPlaceId();
        if (placeId == 0) {
            return;
        }
        // 游离状态
        userData.setPlaceId(0);
        synchronized (getPlaceLock(placeId)) {
            // 从旧的房间移除
            removeMemUser(placeId, userId);
            // 检测占领时间
            checkPlaceSeizeTime(placeId, true);
        }
        // 通知
        Kuang.KuangBattleLeavePlaceSync.Builder syncMsg = Kuang.KuangBattleLeavePlaceSync.newBuilder();
        syncMsg.setUserId(userId);
        syncMsg.setType(type.getValue());
        sendPacketToAll(weekId, groupId, Protocol.U_KUANG_LEAVE_PLACE_SYNC, syncMsg, getMemUserList(placeId));
    }

    /**
     * 移除npc
     */
    private void removeNpc(long userId) {
        if (!isNpc(userId)) {
            return;
        }
        npcUserMap.remove(userId);
        npcDataMap.remove(userId);
    }


    /**
     * 获取宝地上可占领的阵营id
     *
     * @param placeData 宝地
     */
    public int getSeizeCampIdInPlace(CrossKuangBattlePlaceData placeData) {
        int campId = 0;
        Map<Integer, Integer> campPlayerCnt = new ConcurrentHashMap<>();
        for (Long userId : getMemUserList(placeData.getPlaceId())) {
            CrossKuangBattleUserData userData = getUserData(userId);
            if (userData == null || userData.getUserState() == 1) {
                continue;
            }
            campPlayerCnt.put(userData.getCampId(), campPlayerCnt.getOrDefault(userData.getCampId(), 0) + 1);
        }
        int maxCnt = campPlayerCnt.values().stream().mapToInt(entry -> entry).max().orElse(Integer.MIN_VALUE);
        // 可占领的宗门
        List<Integer> canSeizeCampList = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : campPlayerCnt.entrySet()) {
            if (entry.getValue() == maxCnt) {
                canSeizeCampList.add(entry.getKey());
            }
        }
        // 人数相等不可占领，仅有canSeizeCampList数量为1时可占领
        if (canSeizeCampList.size() == 1) {
            campId = canSeizeCampList.get(0);
        } else if (canSeizeCampList.size() > 1) {
            if (canSeizeCampList.contains(placeData.getCampId())) {
                campId = placeData.getCampId();
            } else if (canSeizeCampList.contains(placeData.getLastSeizeCampId())) {
                campId = placeData.getLastSeizeCampId();
            }
        }
        if (campId != 0) {
            placeData.setLastSeizeCampId(campId);
        }
        return campId;
    }

    /**
     * 计算抢占产出
     *
     * @param place 宝地
     */
    private long seizeProduce(CrossKuangBattlePlaceData place) {
        long nowTime = System.currentTimeMillis();
        if (config.getPlaceConfigMap() == null) {
            return 0;
        }
        KuangPlaceConfig placeConfig = config.getPlaceConfigMap().get(place.getPlaceId());
        if (placeConfig == null) {
            return 0;
        }
        long produceTime = (nowTime - place.getLastSeizeRewardTime()) / 1000;
        place.setLastSeizeRewardTime(nowTime);
        return produceTime * placeConfig.getSeizeProduce();
    }


    /**
     * 检测占领时间
     *
     * @param placeId 宝地id
     */
    private void checkPlaceSeizeTime(int placeId, boolean needSync) {
        boolean isSeize = false;
        // 上一次占领的时间
        long lastTotalTime = 0;
        // 产出了多少
        long lastSeizeScore = 0;
        // 抢占成功 需要增加占点战绩的人
        List<Long> needAddScoreUserList = new ArrayList<>();
        int seizeCampId = 0;
        int campId = 0;
        if (config.getPlaceConfigMap() == null) {
            return;
        }
        KuangPlaceConfig placeConfig = config.getPlaceConfigMap().get(placeId);
        if (placeConfig == null) {
            return;
        }
        synchronized (getPlaceLock(placeId)) {
            CrossKuangBattlePlaceData placeData = getPlaceData(placeId);
            if (placeData == null) {
                return;
            }
            // 活动进行中才处理
            if (!isBattleTime()) {
                return;
            }
            long nowTime = System.currentTimeMillis();
            // 获取当前可占领的宗门id
            seizeCampId = getSeizeCampIdInPlace(placeData);
            // 当前占领的宗门
            campId = placeData.getCampId();
            // 只处理宝地
            if (placeConfig.getType() != eKuangBattlePlaceType.Place.getValue()) {
                return;
            }
            for (CrossKuangBattlePlaceSeizeInfo seizeInfo : placeData.getSeizeInfoMap().values()) {
                if (seizeCampId == placeData.getCampId()) {
                    continue;
                }
                // 未占领的判断下
                if (seizeInfo.getCampId() != seizeCampId) {
                    continue;
                }
                if (isSeize) {
                    break;
                }
                int offsetTime = Math.max(0, (int) (nowTime - Math.max(config.getBattleStartTime(roundDay), placeData.getUpdateTime())));
                // 累计计时
                seizeInfo.setSeizeTime(seizeInfo.getSeizeTime() + offsetTime);
                // 抢占成功
                if (seizeInfo.getSeizeTime() >= GameConfig.KUANG_PVP_SEIZE_COUNT_TIME * DateHelper.SECOND_MILLIONS) {
                    lastTotalTime = (nowTime - placeData.getSeizeTime()) / 1000;
                    lastSeizeScore = (nowTime - placeData.getSeizeTime()) / 1000 * placeConfig.getSeizeProduce();
                    placeData.setCampId(seizeInfo.getCampId());
                    placeData.setSeizeTime(nowTime);
                    placeData.setLastNoticeSeizeTime(nowTime);
                    placeData.setLastSeizeRewardTime(nowTime);
                    // 抢占得分
                    addCampScore(placeData.getCampId(), placeConfig.getSeizeScore());
                    // 当前宗门的人增加抢占战绩
                    Set<Long> userList = getMemUserList(placeId);
                    for (Long userId : userList) {
                        CrossKuangBattleUserData userData = getUserData(userId);
                        if (userData == null || userData.getUserState() == 1 || isNpc(userData.getUserId()) || userData.getCampId() != seizeInfo.getCampId()) {
                            continue;
                        }
                        needAddScoreUserList.add(userId);
                    }
                    isSeize = true;
                }
            }
            // 成功占领,其他全部清0
            if (isSeize) {
                for (CrossKuangBattlePlaceSeizeInfo seizeInfo : placeData.getSeizeInfoMap().values()) {
                    seizeInfo.setSeizeTime(0);
                }
                needSync = true;
            }
            placeData.setUpdateTime(nowTime);
            if (needSync) {
                // 同步房间抢占数据
                syncKuangBattlePlaceSeizeMsg(placeData, seizeCampId);
            }
        }
        if (isSeize) {
            CrossKuangBattlePlaceData placeData = getPlaceData(placeId);
            if (campId != 0) {
                // 添加公告
                CrossKuangBattleNoticeData noticeData = new CrossKuangBattleNoticeData();
                noticeData.setCampId(campId);
                noticeData.setNoticeType(eKuangBattleNoticeType.LosePlace);
                noticeData.setContent(placeId + "#" + placeData.getCampId());
                noticeData.setNoticeTime(System.currentTimeMillis());
                noticeData.setIsRoll(Integer.parseInt(GameConfig.XIUXIAN_PVP_NOTICE_PLACE_CHANGED_HANDS));
                addNoticeData(noticeData, 0, 0);
            }

            // 被抢占日志
            CrossAutoLogMgr.add(new LogKuangBattlePlaceSeize(
                    weekId,
                    groupId,
                    campId,
                    roundDay,
                    placeId,
                    1,
                    new Date(),
                    lastTotalTime,
                    lastSeizeScore
            ));
            for (Long userId : needAddScoreUserList) {
                CrossKuangBattleUserData userData;
                synchronized (getPlayerLock(userId)) {
                    userData = getUserData(userId);
                    if (userData == null) {
                        continue;
                    }
                    // 占领战绩
                    addBattleScore(userId, 2, GameConfig.KUANG_PVP_PERSONAL_SCORE_SEIZE);
                    // 加一下参与抢占的地点
                    CrossKuangBattleRecord battleRecord = userData.getBattleRecord();
                    battleRecord.getSeizePlace().add(placeId);
                    userData.setBattleRecord(battleRecord);
                }
                // 判断下抢占是否满足推送公告
                List<String> noticeParamList = StringUtils.stringToStringList(GameConfig.KUANG_PVP_NOTICE_SINGLE_WHEEL_SEIZE_NUM, "\\|");
                String params = noticeParamList.get(1);
                List<Integer> paramList = StringUtils.stringToIntegerList(params, ";");
                int seizeNum = userData.getRoundBattleRecord(roundDay).getSeize();
                if (paramList.contains(seizeNum)) {
                    // 添加公告
                    CrossKuangBattleNoticeData noticeData1 = new CrossKuangBattleNoticeData();
                    noticeData1.setCampId(userData.getCampId());
                    noticeData1.setNoticeType(eKuangBattleNoticeType.TotalSeize);
                    noticeData1.setContent(String.valueOf(seizeNum));
                    noticeData1.setNoticeTime(System.currentTimeMillis());
                    noticeData1.setIsRoll(Integer.parseInt(noticeParamList.get(0)));
                    addNoticeData(noticeData1, userData.getUserId(), 0);
                }
            }
            // 宝地抢占推送
            List<String> noticeParamList = StringUtils.stringToStringList(GameConfig.KUANG_PVP_NOTICE_PLACE_LEVEL, "\\|");
            String params = noticeParamList.get(1);
            List<Integer> paramList = StringUtils.stringToIntegerList(params, ";");
            if (paramList.contains(placeConfig.getLevel())) {
                // 添加公告
                CrossKuangBattleNoticeData noticeData = new CrossKuangBattleNoticeData();
                noticeData.setCampId(seizeCampId);
                noticeData.setNoticeType(eKuangBattleNoticeType.SeizePlace);
                noticeData.setContent(String.valueOf(placeId));
                noticeData.setNoticeTime(System.currentTimeMillis());
                noticeData.setIsRoll(Integer.parseInt(noticeParamList.get(0)));
                addNoticeData(noticeData, 0, 0);
            }
        }
    }


    /**
     * 同步房间抢占数据
     *
     * @param seizeCampId 正在抢占的宗门
     */
    public void syncKuangBattlePlaceSeizeMsg(CrossKuangBattlePlaceData placeData, int seizeCampId) {
        if (placeData == null) {
            return;
        }
        Kuang.KuangBattlePlaceSeizeSyncMsg.Builder builder = Kuang.KuangBattlePlaceSeizeSyncMsg.newBuilder();
        builder.setPlaceId(placeData.getPlaceId());
        // 房间阵营人数
        Map<Integer, Integer> campCnt = new ConcurrentHashMap<>();
        Set<Long> userList = getMemUserList(placeData.getPlaceId());
        for (Long userId : userList) {
            CrossKuangBattleUserData userData = getUserData(userId);
            if (userData == null) {
                continue;
            }
            if (!isBirthPlace(placeData.getPlaceId()) && userData.getUserState() == 1) {
                continue;
            }
            campCnt.put(userData.getCampId(), campCnt.getOrDefault(userData.getCampId(), 0) + 1);
        }
        for (CrossKuangBattlePlaceSeizeInfo seizeInfo : placeData.getSeizeInfoMap().values()) {
            builder.addSeize(parseKuangBattlePlaceSeizeInfoTemp(seizeInfo, campCnt));
        }
        builder.setBeginTime(System.currentTimeMillis());
        if (seizeCampId == placeData.getCampId()) {
            seizeCampId = 0;
        }
        builder.setSeizeCampId(seizeCampId);
        builder.setSeizeTime(placeData.getSeizeTime());
        builder.setCampId(placeData.getCampId());
        sendPacketToAll(weekId, groupId, Protocol.U_KUANG_PLACE_SEIZE_SYNC, builder, userList);
    }

    public boolean isBirthPlace(int placeId) {
        KuangPlaceConfig placeConfig = config.getPlaceConfigMap().get(placeId);
        if (placeConfig == null) {
            return false;
        }
        return placeConfig.getType() != eKuangBattlePlaceType.Place.getValue();
    }

    public CrossKuangBattleCampData getCampData(int campId) {
        return campDataMap.get(campId);
    }


    /**
     * 增加宗门积分
     *
     * @param campId   宗门id
     * @param addScore 增加积分
     */
    public void addCampScore(int campId, long addScore) {
        if (addScore == 0) {
            return;
        }
        long oldScore = 0;
        long newScore = 0;
        synchronized (lock) {
            CrossKuangBattleCampData campData = getCampData(campId);
            if (campData == null) {
                return;
            }
            oldScore = campData.getScore();
            campData.setScore(campData.getScore() + addScore);
            campData.setTotalScore(campData.getTotalScore() + addScore);
            campData.setUpdateScoreTime(System.currentTimeMillis());
            newScore = campData.getScore();
            // 积分榜
            campScoreRankModel.rankChange(new CrossKuangRank(String.valueOf(campData.getCampId()), campData.getScore(), campData.getUpdateScoreTime()));
            // 总积分
            campTotalScoreRankModel.rankChange(new CrossKuangRank(String.valueOf(campData.getCampId()), campData.getTotalScore(), campData.getUpdateScoreTime()));
            needSyncCampScore = true;
            // 更新下积分
            Map<Integer, Map<Integer, CrossKuangBattleCampScoreRecord>> campScoreRecordMap = crossKuangBattleData.getCampScoreRecordMap();
            Map<Integer, CrossKuangBattleCampScoreRecord> recordMap = campScoreRecordMap.getOrDefault(roundDay, new ConcurrentHashMap<>());
            int rankNum = 0;
            for (CrossKuangRank rank : campScoreRankModel.getRankList()) {
                ++rankNum;
                int tempCampId = Integer.parseInt(rank.getId());
                CrossKuangBattleCampScoreRecord record = recordMap.getOrDefault(tempCampId, new CrossKuangBattleCampScoreRecord());
                record.setCampId(tempCampId);
                record.setScore(rank.getValue());
                record.setRank(rankNum);
                recordMap.put(tempCampId, record);
            }
            campScoreRecordMap.put(roundDay, recordMap);
            crossKuangBattleData.setCampScoreRecordMap(campScoreRecordMap);
            // 积分到达指定的值提前结束
            if (checkActivityEnd()) {
                battleEnd = true;
                activityEndSync();
            }
        }
        // 添加公告
        // 检测下结束公告
        List<String> noticeParamList = StringUtils.stringToStringList(GameConfig.KUANG_PVP_NOTICE_BATTLE_END_TIME_SECT_SCORE, "\\|");
        String params = noticeParamList.get(1);
        List<Integer> paramList = StringUtils.stringToIntegerList(params, ";");
        long oldOffsetScore = config.getBattleScoreEndCondition() - oldScore;
        long newOffsetScore = config.getBattleScoreEndCondition() - newScore;
        int canNoticeScore = -1;
        for (int noticeScore : paramList) {
            if (oldOffsetScore > noticeScore && noticeScore >= newOffsetScore) {
                canNoticeScore = noticeScore;
            }
        }
        if (canNoticeScore > 0) {
            // 添加公告
            CrossKuangBattleNoticeData noticeData = new CrossKuangBattleNoticeData();
            noticeData.setCampId(campId);
            noticeData.setNoticeType(eKuangBattleNoticeType.PvpScoreEnd);
            noticeData.setContent(String.valueOf(canNoticeScore));
            noticeData.setNoticeTime(System.currentTimeMillis());
            noticeData.setIsRoll(Integer.parseInt(noticeParamList.get(0)));
            addNoticeData(noticeData, 0, 0);
        }
    }

    private boolean checkActivityEnd() {
        return roundDay != 0 && (System.currentTimeMillis() >= config.getBattleEndTime(roundDay) || getCampMaxScore() >= config.getBattleScoreEndCondition());
    }

    /**
     * 斗法结束通知
     */
    public void activityEndSync() {
        // 添加记录
        if (roundDay == 0 || !battleEnd || endRecordMap.containsKey(roundDay)) {
            return;
        }
        long nowTime = System.currentTimeMillis();
        CrossKuangBattleEndRecord endRecord = new CrossKuangBattleEndRecord();
        endRecord.setWeekId(weekId);
        endRecord.setGroupId(groupId);
        endRecord.setRound(roundDay);
        CrossKuangBattleBestRecord bestSeizeUser = getBestBattleUser(1, 0);
        if (bestSeizeUser != null) {
            // 随机个初始点赞数 5~10
            bestSeizeUser.setLikeCnt(randomHelper.next(5, 11));
            endRecord.setBestSeizeUser(bestSeizeUser);
        }
        CrossKuangBattleBestRecord bestKillUser = getBestBattleUser(2, 0);
        if (bestKillUser != null) {
            // 随机个初始点赞数 5~10
            bestKillUser.setLikeCnt(randomHelper.next(5, 11));
            endRecord.setBestKillUser(bestKillUser);
        }
        // 宗门最佳抢占map
        Map<Integer, CrossKuangBattleBestRecord> campBestSeizeUserMap = new ConcurrentHashMap<>();
        // 宗门最佳击杀map
        Map<Integer, CrossKuangBattleBestRecord> campBestKillUserMap = new ConcurrentHashMap<>();
        for (int campId : campDataMap.keySet()) {
            CrossKuangBattleBestRecord campBestSeizeUser = new CrossKuangBattleBestRecord();
            CrossKuangBattleBestRecord tempSeizeUser = getBestBattleUser(1, campId);
            if (tempSeizeUser != null) {
                campBestSeizeUser = tempSeizeUser;
            }
            campBestSeizeUserMap.put(campId, campBestSeizeUser);
            CrossKuangBattleBestRecord campBestKillUser = new CrossKuangBattleBestRecord();
            CrossKuangBattleBestRecord tempKillUser = getBestBattleUser(2, campId);
            if (tempKillUser != null) {
                campBestKillUser = tempKillUser;
            }
            campBestKillUserMap.put(campId, campBestKillUser);
        }
        endRecord.setCampBestSeizeUserMap(campBestSeizeUserMap);
        endRecord.setCampBestKillUserMap(campBestKillUserMap);
        endRecord.setEndTime(nowTime);
        endRecord.setInsertOption();
        endRecordMap.put(roundDay, endRecord);
        // 同步活动结束
        for (long userId : userDataMap.keySet()) {
            crossBattleSync(userId);
        }

        // 处理下宝地记录
        for (CrossKuangBattlePlaceData placeData : placeDataMap.values()) {
            KuangPlaceConfig placeConfig = config.getPlaceConfigMap().get(placeData.getPlaceId());
            // 被抢占日志
            CrossAutoLogMgr.add(new LogKuangBattlePlaceSeize(
                    weekId,
                    groupId,
                    placeData.getCampId(),
                    roundDay,
                    placeData.getPlaceId(),
                    2,
                    new Date(),
                    (nowTime - placeData.getSeizeTime()) / 1000,
                    (nowTime - placeData.getSeizeTime()) / 1000 * placeConfig.getSeizeProduce()
            ));
        }
    }

    /**
     * 获取最佳用户
     *
     * @param type   1:抢点 2:击杀
     * @param campId 宗门id,0为获取所有
     */
    public CrossKuangBattleBestRecord getBestBattleUser(int type, int campId) {
        int maxCnt = 0;
        long maxScore = 0;
        long maxUserId = 0;
        CrossKuangBattleRecord battleRecord = new CrossKuangBattleRecord();
        for (CrossKuangBattleUserData userData : userDataMap.values()) {
            // 获取宗门的
            if (campId != 0 && userData.getCampId() != campId) {
                continue;
            }
            CrossKuangBattleRecord totalBattleRecord = userData.getRoundBattleRecord(roundDay);
            // 对比吧
            if (type == 1) {
                if (totalBattleRecord.getSeize() >= maxCnt) {
                    // 积分相等比较战绩
                    if (totalBattleRecord.getSeize() == maxCnt && totalBattleRecord.getSeizeScore() < maxScore) {
                        continue;
                    }
                    maxCnt = totalBattleRecord.getSeize();
                    maxScore = totalBattleRecord.getSeizeScore();
                    maxUserId = userData.getUserId();
                    battleRecord = totalBattleRecord;
                }
            } else if (type == 2) {
                if (totalBattleRecord.getKill() >= maxCnt) {
                    // 积分相等比较战绩
                    if (totalBattleRecord.getKill() == maxCnt && totalBattleRecord.getKillScore() < maxScore) {
                        continue;
                    }
                    maxCnt = totalBattleRecord.getKill();
                    maxScore = totalBattleRecord.getKillScore();
                    maxUserId = userData.getUserId();
                    battleRecord = totalBattleRecord;
                }
            }
        }
        if (maxUserId == 0) {
            return null;
        }
        CrossKuangBattleBestRecord bestBattleRecord = new CrossKuangBattleBestRecord();
        bestBattleRecord.setUserId(maxUserId);
        bestBattleRecord.setCampId(getCampByUserId(maxUserId));
        bestBattleRecord.setBattleRecord(battleRecord);

        return bestBattleRecord;
    }

    public boolean isCampNotice(CrossKuangBattleNoticeData noticeData) {
        if (noticeData == null) {
            return false;
        }
        return eKuangBattleNoticeType.Appoint == noticeData.getNoticeType()
                || eKuangBattleNoticeType.CancelAppoint == noticeData.getNoticeType()
                || eKuangBattleNoticeType.MajorMarkPlace == noticeData.getNoticeType()
                || eKuangBattleNoticeType.MinorMarkPlace == noticeData.getNoticeType()
                || eKuangBattleNoticeType.LosePlace == noticeData.getNoticeType();
    }

    /**
     * 增加公告
     *
     * @param noticeData 公告信息
     * @param userId1    操作者id
     * @param userId2    被操作者id
     */
    public void addNoticeData(CrossKuangBattleNoticeData noticeData, long userId1, long userId2) {
        // 添加操作者信息
        if (userId1 != 0) {
            CrossKuangBattleUserData userData = getUserData(userId1);
            if (userData != null) {
                CrossKuangBattleNoticeUserData noticeUserData = new CrossKuangBattleNoticeUserData();
                noticeUserData.setUserId(userData.getUserId());
                if (isNpc(userId1)) {
                    CrossKuangBattleNpcData npcData = npcDataMap.get(userId1);
                    if (npcData != null) {
                        noticeUserData.setNickName(npcData.getNickName());
                        noticeUserData.setServerId(npcData.getServerId());
                        noticeUserData.setDecoration(npcData.getDecoration());
                    }
                } else {
                    CrossUserBaseInfo userBaseInfo = CrossUserMgr.getCrossUserBaseInfo(userId1);
                    if (userBaseInfo != null && userBaseInfo.getUserBaseInfo() != null) {
                        noticeUserData.setNickName(userBaseInfo.getUserBaseInfo().getNickName());
                        noticeUserData.setServerId(userBaseInfo.getUserBaseInfo().getServerId());
                        noticeUserData.setDecoration(userBaseInfo.getUserBaseInfo().getDecoration());
                    }
                }
                noticeData.setUser1(noticeUserData);
            }
        }
        // 添加被操作者信息
        if (userId2 != 0) {
            CrossKuangBattleUserData userData = getUserData(userId2);
            if (userData != null) {
                CrossKuangBattleNoticeUserData noticeUserData = new CrossKuangBattleNoticeUserData();
                noticeUserData.setUserId(userData.getUserId());
                if (isNpc(userId2)) {
                    CrossKuangBattleNpcData npcData = npcDataMap.get(userId2);
                    if (npcData != null) {
                        noticeUserData.setNickName(npcData.getNickName());
                        noticeUserData.setServerId(npcData.getServerId());
                        noticeUserData.setDecoration(npcData.getDecoration());
                    }
                } else {
                    CrossUserBaseInfo userBaseInfo = CrossUserMgr.getCrossUserBaseInfo(userId2);
                    if (userBaseInfo != null && userBaseInfo.getUserBaseInfo() != null) {
                        noticeUserData.setNickName(userBaseInfo.getUserBaseInfo().getNickName());
                        noticeUserData.setServerId(userBaseInfo.getUserBaseInfo().getServerId());
                        noticeUserData.setDecoration(userBaseInfo.getUserBaseInfo().getDecoration());
                    }
                }
                noticeData.setUser2(noticeUserData);
            }
        }
        Kuang.KuangBattleNoticeSyncMsg.Builder syncMsg = Kuang.KuangBattleNoticeSyncMsg.newBuilder();
        if (isCampNotice(noticeData)) {
            // 宗门公告
            int campId = noticeData.getCampId();
            if (campId == 0) {
                return;
            }
            // 添加宗门公告
            synchronized (campNoticeDataMap) {
                LinkedList<CrossKuangBattleNoticeData> list = campNoticeDataMap.getOrDefault(campId, new LinkedList<>());
                while (list.size() > GameConfig.KUANG_PVP_NOTICE_NUM) {
                    list.removeFirst();
                }
                list.addLast(noticeData);
                campNoticeDataMap.put(campId, list);
            }
            Kuang.KuangBattleNoticeTemp.Builder noticeTemp = parseKuangBattleNoticeTemp(noticeData);
            if (noticeTemp != null) {
                syncMsg.setCampNotice(noticeTemp);
                // 推送公告给宗门在线成员
                Set<Long> list = getUserIdListInActivityByCampId(campId);
                sendPacketToAll(weekId, groupId, Protocol.U_KUANG_NOTICE_SYNC, syncMsg, list);
            }
        } else {
            // 全服公告
            synchronized (noticeDataList) {
                while (noticeDataList.size() > GameConfig.KUANG_PVP_NOTICE_NUM) {
                    noticeDataList.removeFirst();
                }
                noticeDataList.add(noticeData);
            }
            Kuang.KuangBattleNoticeTemp.Builder noticeTemp = parseKuangBattleNoticeTemp(noticeData);
            if (noticeTemp != null) {
                syncMsg.setNotice(noticeTemp);
                // 推送公告给在线用户
                sendPacketToAll(weekId, groupId, Protocol.U_KUANG_NOTICE_SYNC, syncMsg, inBattleUserSet);
            }
        }
    }

    public Set<Long> getUserIdListInActivityByCampId(int campId) {
        Set<Long> list = new HashSet<>();
        for (CrossKuangBattleUserData userData : userDataMap.values()) {
            // 只同步本阵营的玩家
            if (userData.getCampId() != campId) {
                continue;
            }
            list.add(userData.getUserId());
        }
        return list;
    }


    /**
     * 进入活动
     *
     * @param userId
     * @return
     */
    public int enterBattleByCmd(long userId) {
        // 判断下资格
//        if (!crossKuangBattleData.isLockState()) {
//            return GameErrorCode.E_KUANG_BATTLE_IN_LOCK_STATE;
//        }
        Kuang.KuangBattleEnterRespMsg.Builder builder = Kuang.KuangBattleEnterRespMsg.newBuilder();
        builder.setRet(0);
        // 默认都有资格
        builder.setAble(true);
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
        }
        // 设置下进入过战斗
        userData.setEnterBattle(true);

        inBattleUserSet.add(userId);
        CrossKuangBattleCampData campData = getCampData(userData.getCampId());

        // 如果是死亡状态，处理下复活
        if (userData.getUserState() == 1) {
            revive(userData);
        }
        // 进入战斗默认给丢到出生点
        // 离开原来的房间
        leavePlace(userData, eKuangBattleLeaveType.UserLeave);
        // 进入出生点
        joinPlace(userData.getCampId(), userData);
        // 用户数据
        builder.setBattleUserData(parseKuangBattleUserDataTemp(userData));
        // 阵营信息
        builder.setCamp(parseKuangBattleCampTemp(campData));
        // 房间信息
        Kuang.KuangBattlePlaceInfoTemp.Builder placeInfoTemp = parseKuangBattlePlaceInfoTemp(getPlaceData(userData.getPlaceId()));
        if (placeInfoTemp != null) {
            builder.setPlace(placeInfoTemp);
        }

        // 公告信息
        Kuang.KuangBattleNoticeListMsg.Builder noticeList = Kuang.KuangBattleNoticeListMsg.newBuilder();
        // 全服公告
        for (CrossKuangBattleNoticeData noticeData : noticeDataList) {
            Kuang.KuangBattleNoticeTemp.Builder noticeTemp = parseKuangBattleNoticeTemp(noticeData);
            if (noticeTemp != null) {
                noticeList.addNotice(noticeTemp);
            }
        }
        // 宗门公告
        LinkedList<CrossKuangBattleNoticeData> campNoticeDataList = campNoticeDataMap.get(userData.getCampId());
        if (campNoticeDataList != null) {
            for (CrossKuangBattleNoticeData noticeData : campNoticeDataList) {
                Kuang.KuangBattleNoticeTemp.Builder noticeTemp = parseKuangBattleNoticeTemp(noticeData);
                if (noticeTemp != null) {
                    noticeList.addCampNotice(noticeTemp);
                }
            }
        }
        builder.setNoticeList(noticeList);

        sendPacket(ClientProtocol.U_KUANG_ENTER_BATTLE, builder, userId);

        // 同步下积分
        Kuang.KuangBattleCampScoreSyncMsg.Builder campScoreBuilder = Kuang.KuangBattleCampScoreSyncMsg.newBuilder();
        List<Kuang.KuangBattleCampScoreSyncTemp.Builder> list = getKuangCampScoreTempList();
        for (Kuang.KuangBattleCampScoreSyncTemp.Builder temp : list) {
            campScoreBuilder.addCampScore(temp);
        }
        sendPacket(Protocol.U_KUANG_CAMP_SCORE_SYNC, campScoreBuilder, userId);
        return 0;
    }

    /**
     * 检查财神技能
     */
    private void checkUserSkill(CrossKuangBattleUserData userData) {
        if (userData == null) {
            return;
        }
        // 财神等级
        int honoraryTitleLevel = Math.toIntExact(userData.getAttributeMap().getOrDefault(eKuangAttributeType.AttributeEnum_HonoraryTitleLevel, 0L));
        for (CrossKuangBattleUserSkill skill : userData.getSkillList()) {
            if (skill.getType() == 1 && skill.getLittleType() == honoraryTitleLevel) {
                // 已存在就不处理了
                return;
            }
        }
        // 不存在或者财神技能变更,先移除旧的财神技能
        userData.getSkillList().removeIf(skill -> skill.getType() == 1);
        if (honoraryTitleLevel > 0) {
            // 添加新的财神技能
            userData.getSkillList().add(new CrossKuangBattleUserSkill(1, honoraryTitleLevel));
        }
        userData.setUpdateOption();
    }

    public int useSkillByCmd(long userId, int type, int littleType) {
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
        }
        CrossKuangBattleUserSkill skill = userData.getSkill(type, littleType);
        if (skill == null) {
            return GameErrorCode.E_KUANG_BATTLE_SKILL_NOT_FOUND;
        }
        long nowTime = System.currentTimeMillis();
        if (nowTime < skill.getReadyTime()) {
            return GameErrorCode.E_KUANG_BATTLE_SKILL_TIME_NO_ENOUGH;
        }
        // 目前只有财神技能
        if (type == 1) {
            if (!config.getSkillParamMap().containsKey(littleType)) {
                return GameErrorCode.E_KUANG_CONFIG_NOT_FOUND;
            }
            Map<Integer, Integer> map = config.getSkillParamMap().get(littleType);
            map.forEach((k, v) -> {
                CrossKuangBattleUserBuff battleUserBuff = new CrossKuangBattleUserBuff();
                eKuangAttributeType attributeType = eKuangAttributeType.forValue(k);
                battleUserBuff.setType(attributeType);
                battleUserBuff.setValue(v.longValue());
                battleUserBuff.setExpireTime(nowTime + GameConfig.KUANG_PLAYER_SKILL_TIME * DateHelper.SECOND_MILLIONS);
                userData.addBuff(battleUserBuff);
            });
            // 改cd
            skill.setReadyTime(nowTime + GameConfig.KUANG_PLAYER_SKILL_NEED_ANGER * DateHelper.SECOND_MILLIONS);
        }
        Kuang.KuangBattleUseSkillRespMsg.Builder respMsg = Kuang.KuangBattleUseSkillRespMsg.newBuilder();
        respMsg.setRet(0);
        respMsg.setBattleUserData(parseKuangBattleUserDataTemp(userData));
        sendPacket(Protocol.U_KUANG_BATTLE_USE_SKILL, respMsg, userId);

        // 同步技能信息
        Kuang.KuangBattleUseSkillSyncMsg.Builder syncMsg = Kuang.KuangBattleUseSkillSyncMsg.newBuilder();
        syncMsg.setUserId(userId);
        syncMsg.setType(type);
        syncMsg.setLittleType(littleType);
        for (CrossKuangBattleUserBuff userBuff : userData.getBuffList()) {
            syncMsg.addBuffList(parseKuangBattleBuffTemp(userBuff));
        }
        // 同步给房间的用户
        sendPacketToAll(weekId, groupId, Protocol.U_KUANG_USE_SKILL_SYNC, syncMsg, getMemUserList(userData.getPlaceId()));
        return 0;
    }


    /**
     * 离开pvp
     */
    public int leaveBattleByCmd(long userId) {
        inBattleUserSet.remove(userId);
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData != null) {
            // 如果在房间状态，则退出房间
            leavePlace(userData, eKuangBattleLeaveType.UserLeave);
            Kuang.KuangBattleLeaveRespMsg.Builder builder = Kuang.KuangBattleLeaveRespMsg.newBuilder();
            builder.setRet(0);
            sendPacket(ClientProtocol.U_KUANG_LEAVE_BATTLE, builder, userId);
        }
        return 0;
    }


    /**
     * 进入(传送)房间
     *
     * @param userId 玩家id
     */
    public int enterPlaceByCmd(long userId, int placeId) {
        CrossKuangBattlePlaceData placeData = getPlaceData(placeId);
        if (placeData == null) {
            return GameErrorCode.E_KUANG_BATTLE_PLACE_NOT_FOUND;
        }
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
        }
        // 判断下房间的人数是否上限
        if (placeId != 0 && checkCampPlayerLimit(userData.getCampId(), placeId)) {
            return GameErrorCode.E_KUANG_BATTLE_PLACE_USER_LIMIT;
        }
        if (!isBirthPlace(placeId)) {
            // 死亡状态只允许回出生点且不读cd
            if (userData.getUserState() == 1) {
                return GameErrorCode.E_KUANG_BATTLE_ONLY_GO_TO_BIRTH;
            }
            // 非死亡状态
            long nowTime = System.currentTimeMillis();
            if (nowTime < userData.getTransferTime()) {
                // 没到传送时间
                return GameErrorCode.E_KUANG_BATTLE_DONT_TRANSFER;
            }
            // 传送时间
            userData.setTransferTime(nowTime + DateHelper.SECOND_MILLIONS * GameConfig.KUANG_PVP_DELIVERY_CD);
        } else {
            // 如果是死亡状态，处理下复活
            if (userData.getUserState() == 1) {
                revive(userData);
            }
        }
        // 离开旧房间
        leavePlace(userData, eKuangBattleLeaveType.Transfer);
        // 加入房间
        joinPlace(placeId, userData);
        Kuang.KuangBattleEnterPlaceRespMsg.Builder builder = Kuang.KuangBattleEnterPlaceRespMsg.newBuilder();
        builder.setRet(0);
        Kuang.KuangBattlePlaceInfoTemp.Builder placeInfoTemp = parseKuangBattlePlaceInfoTemp(getPlaceData(userData.getPlaceId()));
        if (placeInfoTemp != null) {
            builder.setPlace(placeInfoTemp);
        }
        builder.setPlaceId(placeId);
        builder.setTransferTime(userData.getTransferTime());
        sendPacket(ClientProtocol.U_KUANG_ENTER_PLACE, builder, userId);
        return 0;
    }

    /**
     * 离开房间Cmd
     *
     * @param userId 玩家id
     */
    public int leavePlaceByCmd(long userId) {
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
        }
        // 离开房间
        leavePlace(userData, eKuangBattleLeaveType.UserLeave);
        Kuang.KuangBattleLeavePlaceRespMsg.Builder builder = Kuang.KuangBattleLeavePlaceRespMsg.newBuilder();
        builder.setRet(0);
        sendPacket(ClientProtocol.U_KUANG_LEAVE_PLACE, builder, userId);
        return 0;
    }

    /**
     * 移动
     *
     * @param userId   玩家id
     * @param position 位置信息
     */
    public int moveByCmd(long userId, CrossKuangBattlePosition position) {
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
        }
        if (!isBirthPlace(userData.getPlaceId()) && userData.getUserState() == 1) {
            return GameErrorCode.E_KUANG_BATTLE_USER_DIE;
        }
        // 移动
        move(userData, position);
        Kuang.KuangBattleMoveRespMsg.Builder builder = Kuang.KuangBattleMoveRespMsg.newBuilder();
        builder.setRet(0);
        sendPacket(ClientProtocol.U_KUANG_BATTLE_MOVE, builder, userId);
        return 0;
    }


    /**
     * 移动逻辑
     *
     * @param userData 用户数据
     * @param position 位置信息
     */
    private void move(CrossKuangBattleUserData userData, CrossKuangBattlePosition position) {
        userData.setPosition(position);
        userData.setLastPingPlaceTime(position.getTime());
    }


    /**
     * 攻击
     */
    public int attackByCmd(long userId, long attackedUserId) {
        long nowTime = System.currentTimeMillis();
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_KOWLOON_USER_NOT_FOUND;
        }
        if (userData.getUserState() == 1) {
            return GameErrorCode.E_KUANG_BATTLE_USER_DIE;
        }
        // 获取被攻击人的信息
        long leftHp;
        CrossKuangBattleAttackHelper attackHelper;
        int placeId;
        // 我的战斗属性
        Map<eKuangAttributeType, Long> attackAttributeMap = userData.getActualAttributeMap();
        // 攻速
        long atkSpeed = attackAttributeMap.getOrDefault(eKuangAttributeType.AttributeEnum_AttackSpeed, 1000L);
        // 攻速千分比 区间只能1-1000  程序做个保护
        int speedRatio = Math.max(1, Math.min(1000, GameConfig.KUANG_PVP_ATTACK_SPEED_RATIO));
        // 算下一秒攻击多少下  最低0.5,最大5下，特殊处理下 程序做个保护
        double atkCount = Math.min(5, Math.max(0.5, BigDecimal.valueOf(atkSpeed).divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).multiply(BigDecimal.valueOf(speedRatio)).divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).doubleValue()));
        // 攻击间隔
        long atkTime = BigDecimal.valueOf(1000).divide(BigDecimal.valueOf(atkCount), 0, RoundingMode.UP).longValue();
        if (nowTime - userData.getAttackTime() < atkTime) {
            return GameErrorCode.E_KUANG_ATTACK_TIME_LIMIT;
        }
        placeId = userData.getPlaceId();

        // 对手的连杀数
        int attackedUserKillNum = 0;
        // 打架获取房间锁
        synchronized (getPlaceLock(placeId)) {
            // 被攻击者
            CrossKuangBattleUserData attackedUserData = getUserData(attackedUserId);
            if (attackedUserData == null) {
                return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
            }
            // 被攻击者战斗属性
            Map<eKuangAttributeType, Long> attackedAttributeMap = attackedUserData.getActualAttributeMap();
            // 判断是否能攻击
            if (attackedAttributeMap.getOrDefault(eKuangAttributeType.AttributeEnum_CurHp, 0L) == 0) {
                return GameErrorCode.E_KUANG_ATTACK_TARGET_NOT_FOUND;
            }
            if (attackedUserData.getPlaceId() != placeId) {
                return GameErrorCode.E_KUANG_ATTACK_TARGET_NOT_FOUND;
            }
            if (attackedUserData.getCampId() == userData.getCampId()) {
                return GameErrorCode.E_KUANG_DONT_ATTACK_THE_SAME_CAMP;
            }
            attackedUserKillNum = attackedUserData.getBattleRecord().getKill();
            // 攻击
            attackHelper = attack(placeId, userData, attackedUserData);
            // 被打同步消息
            syncAttackedUser(userData, attackedUserData, attackHelper);
            // 记录一下攻击时间
            userData.setAttackTime(nowTime);
            leftHp = attackHelper.getAttackedHp();
        }

        long attackScore = 0;
        // 成功击杀
        if (leftHp == 0) {
            // 检测占领时间
            checkPlaceSeizeTime(placeId, true);

            // 成功击杀同步房间被打记录
            syncPlaceAttack(placeId);

            //  攻击得分
            List<String> killParamList = StringUtils.stringToStringList(GameConfig.KUANG_PVP_PERSONAL_SCORE_KILL, "\\|");
            for (String killParam : killParamList) {
                String[] split = killParam.split(";");
                if (attackedUserKillNum >= Integer.parseInt(split[0])) {
                    attackScore = Long.parseLong(split[1]);
                }
            }
            // 记录战绩
            addBattleScore(userId, 1, attackScore);
            // 判断下击杀是否满足单条命推送公告
            List<String> noticeParamList = StringUtils.stringToStringList(GameConfig.KUANG_PVP_NOTICE_SINGLE_TIME_KILL_NUM, "\\|");
            String params = noticeParamList.get(1);
            List<Integer> paramList = StringUtils.stringToIntegerList(params, ";");
            int killNum = userData.getBattleRecord().getKill();
            // 记录下连杀数
            attackHelper.setKillNum(killNum);
            if (paramList.contains(killNum)) {
                // 添加单条命击杀公告
                CrossKuangBattleNoticeData noticeData = new CrossKuangBattleNoticeData();
                noticeData.setCampId(userData.getCampId());
                noticeData.setNoticeType(eKuangBattleNoticeType.Kill);
                noticeData.setContent(String.valueOf(killNum));
                noticeData.setNoticeTime(nowTime);
                noticeData.setIsRoll(Integer.parseInt(noticeParamList.get(0)));
                addNoticeData(noticeData, userData.getUserId(), 0);
            }
            // 判断下击杀是否满足单轮推送公告
            List<String> noticeParamList1 = StringUtils.stringToStringList(GameConfig.KUANG_PVP_NOTICE_SINGLE_WHEEL_KILL_NUM, "\\|");
            String params1 = noticeParamList1.get(1);
            List<Integer> paramList1 = StringUtils.stringToIntegerList(params1, ";");
            int roundKillNum = userData.getRoundBattleRecord(roundDay).getKill();
            if (paramList1.contains(roundKillNum)) {
                // 添加本轮斗法累计击杀公告
                CrossKuangBattleNoticeData noticeData = new CrossKuangBattleNoticeData();
                noticeData.setCampId(userData.getCampId());
                noticeData.setNoticeType(eKuangBattleNoticeType.TotalKill);
                noticeData.setContent(String.valueOf(roundKillNum));
                noticeData.setNoticeTime(nowTime);
                noticeData.setIsRoll(Integer.parseInt(noticeParamList1.get(0)));
                addNoticeData(noticeData, userData.getUserId(), 0);
            }

            // 记录一下击杀日志
            CrossAutoLogMgr.add(new LogKuangBattleAttack(
                    weekId,
                    groupId,
                    userData.getCampId(),
                    roundDay,
                    userId,
                    attackedUserId,
                    attackScore,
                    new Date()
            ));
        }

        Kuang.KuangBattleAttackRespMsg.Builder builder = Kuang.KuangBattleAttackRespMsg.newBuilder();
        builder.setRet(0);
        builder.setAttackTime(nowTime);
        builder.setAttack(parseKuangBattleAttackedTemp(attackHelper));
        builder.setAttackScore(attackScore);
        sendPacket(ClientProtocol.U_KUANG_BATTLE_ATTACK, builder, userId);
        return 0;
    }

    /**
     * 攻击
     *
     * @param placeId      房间id
     * @param attackUser   攻击者
     * @param attackedUser 被攻击者
     */
    public CrossKuangBattleAttackHelper attack(int placeId, CrossKuangBattleUserData attackUser, CrossKuangBattleUserData attackedUser) {
        // 添加攻击记录
        CrossKuangBattleAttackHelper attackHelper = new CrossKuangBattleAttackHelper();
        attackHelper.setAttackUserId(attackUser.getUserId());
        attackHelper.setAttackedUserId(attackedUser.getUserId());
        // 我方战斗属性
        Map<eKuangAttributeType, Long> attackAttributeMap = attackUser.getActualAttributeMap();
        // 对方战斗属性
        Map<eKuangAttributeType, Long> attackedAttributeMap = attackedUser.getActualAttributeMap();
        // 攻击逻辑
        // 先判断是否能闪避本次攻击
        // 闪避几率 = (对方闪避值千分数 - 我方命中值千分数) / 1000
        long dodgeValue = attackedAttributeMap.getOrDefault(eKuangAttributeType.AttributeEnum_Dodge, 0L) - attackAttributeMap.getOrDefault(eKuangAttributeType.AttributeEnum_Hit, 0L);
        if (dodgeValue > GameConfig.KUANG_MAX_SHANBI_SHANGXIAN) {
            dodgeValue = GameConfig.KUANG_MAX_SHANBI_SHANGXIAN;
        }
        boolean isDodge = randomHelper.next(0, 1000) < Math.max(0, dodgeValue);
        if (!isDodge) {
            // 没闪避才继续往下处理
            // 暴击几率 = (我方暴击值千分数 - 对方坚韧值千分数) / 1000
            boolean isCrit = randomHelper.next(0, 1000) < Math.max(0, attackAttributeMap.getOrDefault(eKuangAttributeType.AttributeEnum_Critical, 0L) - attackedAttributeMap.getOrDefault(eKuangAttributeType.AttributeEnum_Toughness, 0L));
            // 基础攻击
            long attackHp = attackAttributeMap.getOrDefault(eKuangAttributeType.AttributeEnum_Attack, 0L);
            if (isCrit) {
                attackHp *= 2;
            }
            // 实际扣血
            attackHp = attackedUser.offsetHp(-attackHp);
            // 吸血
            long suckHp = BigDecimal.valueOf(attackHp).multiply(BigDecimal.valueOf(attackAttributeMap.getOrDefault(eKuangAttributeType.AttributeEnum_LifeSteal, 0L))).divide(BigDecimal.valueOf(1000), 0, RoundingMode.DOWN).longValue();
            // 实际吸血
            suckHp = attackUser.offsetHp(suckHp);
            attackHelper.setCrit(isCrit);
            attackHelper.setHp(attackHp);
            attackHelper.setSuckHp(suckHp);
        }
        attackHelper.setDodge(isDodge);
        attackHelper.setAttackHp(attackUser.getCurHp());
        attackHelper.setAttackedHp(attackedUser.getCurHp());
        addBattleAttackSyncData(placeId, attackHelper);
        return attackHelper;
    }

    /**
     * 结算数据点赞
     */
    public int endDataLikeByCmd(long userId, int round, int type) {
        CrossKuangBattleEndRecord endRecord = endRecordMap.get(round);
        if (endRecord == null) {
            return GameErrorCode.E_KUANG_PARAM_ERROR;
        }
        // 击杀王
        int resultCnt = 0;
        if (type == 1) {
            CrossKuangBattleBestRecord bestKillUser = endRecord.getBestKillUser();
            resultCnt = bestKillUser.getLikeCnt() + 1;
            bestKillUser.setLikeCnt(resultCnt);
        } else if (type == 2) {
            CrossKuangBattleBestRecord bestSeizeUser = endRecord.getBestSeizeUser();
            resultCnt = bestSeizeUser.getLikeCnt() + 1;
            bestSeizeUser.setLikeCnt(resultCnt);
        }
        endRecord.setUpdateOption();
        Kuang.KuangBattleEndDataLikeRespMsg.Builder builder = Kuang.KuangBattleEndDataLikeRespMsg.newBuilder();
        builder.setRet(0);
        builder.setLikeCnt(resultCnt);
        sendPacket(ClientProtocol.U_KUANG_BATTLE_END_DATA_LIKE, builder, userId);
        return 0;
    }


    /**
     * 添加被打同步消息
     */
    public void addBattleAttackSyncData(int placeId, CrossKuangBattleAttackHelper attack) {
        synchronized (attackSyncListMap) {
            List<CrossKuangBattleAttackHelper> attackSyncList = attackSyncListMap.getOrDefault(placeId, new ArrayList<>());
            attackSyncList.add(attack);
            attackSyncListMap.put(placeId, attackSyncList);
        }
    }

    /**
     * 被打同步
     */
    private void syncAttackedUser(CrossKuangBattleUserData attackUserData, CrossKuangBattleUserData attackedUserData, CrossKuangBattleAttackHelper attackHelper) {
        Kuang.KuangBattleAttackedUserSyncMsg.Builder builder = Kuang.KuangBattleAttackedUserSyncMsg.newBuilder();
        if (attackedUserData.getCurHp() <= 0) {
            // 送回出生点
            // 复活时间
            List<Integer> paramList = StringUtils.stringToIntegerList(GameConfig.KUANG_PVP_RESURRECTION_CD, "\\|");
            int initCd = paramList.get(0);
            int addCd = paramList.get(1);
            int maxCd = paramList.get(2);
            int cd = Math.min(maxCd, initCd + attackedUserData.getReviveCnt() * addCd);
            long nowTime = System.currentTimeMillis();
            attackedUserData.setReviveTime(nowTime + DateHelper.SECOND_MILLIONS * cd);
            // 记录一下被打时间
            attackedUserData.setAttackedTime(nowTime);
            // 本条命战绩
            builder.setBattleScore(parseKuangBattleBattleScoreTemp(attackedUserData.getBattleRecord()));
            // 本轮战绩
            builder.setTotalBattleScore(parseKuangBattleBattleScoreTemp(attackedUserData.getRoundBattleRecord(roundDay)));

            // 清空下战绩
            attackedUserData.setBattleRecord(new CrossKuangBattleRecord());

            if (isNpc(attackedUserData.getUserId())) {
                // 离开原来的房间
                leavePlace(attackedUserData, eKuangBattleLeaveType.Kill);
                joinPlace(attackedUserData.getCampId(), attackedUserData);
                // npc不需要往下处理了
                return;
            }
        }
        // 通知被打的人
        builder.setAttackUserData(parseKuangBattleOtherUserTemp(attackUserData));
        builder.setAttack(parseKuangBattleAttackedTemp(attackHelper));
        builder.setBattleUserData(parseKuangBattleUserDataTemp(attackedUserData));
        sendPacket(ClientProtocol.U_KUANG_ATTACKED_USER_SYNC, builder, attackedUserData.getUserId());
    }


    /**
     * 获取房间信息
     */
    public int getPlaceDataByCmd(long userId) {
        Kuang.KuangBattleGetPlaceInfoRespMsg.Builder respMsg = Kuang.KuangBattleGetPlaceInfoRespMsg.newBuilder();
        List<CrossKuangBattlePlaceData> list = new ArrayList<>(placeDataMap.values());
        for (CrossKuangBattlePlaceData placeData : list) {
            Kuang.KuangBattlePlaceSimpleTemp.Builder place = Kuang.KuangBattlePlaceSimpleTemp.newBuilder();
            place.setPlaceId(placeData.getPlaceId());
            place.setSeizeCampId(placeData.getCampId());
            // 阵营人数
            Map<Integer, Integer> campCnt = new ConcurrentHashMap<>();
            for (Long tempUserId : getMemUserList(placeData.getPlaceId())) {
                CrossKuangBattleUserData userData = getUserData(tempUserId);
                if (userData == null) {
                    continue;
                }
                // 出生地等待复活的也显示
                if (!isBirthPlace(place.getPlaceId()) && userData.getUserState() == 1) {
                    continue;
                }
                campCnt.put(userData.getCampId(), campCnt.getOrDefault(userData.getCampId(), 0) + 1);
            }
            for (Map.Entry<Integer, Integer> entry : campCnt.entrySet()) {
                // 阵营0的话就不加进去了
                if (entry.getKey() == 0 || entry.getValue() == 0) {
                    continue;
                }
                Kuang.KuangBattlePlaceCampMemberTemp.Builder member = Kuang.KuangBattlePlaceCampMemberTemp.newBuilder();
                member.setCampId(entry.getKey());
                member.setNum(entry.getValue());
                place.addCampMember(member);
            }
            respMsg.addPlace(place);
        }
        respMsg.setRet(0);
        sendPacket(ClientProtocol.U_KUANG_GET_PLACE_DATA, respMsg, userId);
        return 0;
    }

    /**
     * 获取阵营玩家信息
     */
    public int getCampUserListByCmd(long userId, int campId) {
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
        }
        Kuang.KuangBattleGetCampUserListRespMsg.Builder respMsg = Kuang.KuangBattleGetCampUserListRespMsg.newBuilder();
        // 获取本阵营玩家信息
        for (CrossKuangBattleUserData tempUserData : userDataMap.values()) {
            if (tempUserData.getCampId() == campId) {
                Kuang.KuangBattleUserDetailTemp.Builder userDetailTemp = parseKuangBattleUserDetailTemp(tempUserData);
                if (userDetailTemp != null) {
                    respMsg.addUser(userDetailTemp);
                }
            }
        }
        respMsg.setRet(0);
        sendPacket(ClientProtocol.U_KUANG_GET_CAMP_USER_LIST, respMsg, userId);
        return 0;
    }

    /**
     * 获取pvp战报
     */
    public int getBattleReportByCmd(long userId, long targetUserId) {
        Kuang.KuangBattleGetReportRespMsg.Builder respMsg = Kuang.KuangBattleGetReportRespMsg.newBuilder();
        // 获取pvp战报
        // 个人战报
        CrossKuangBattleUserData userData = getUserData(targetUserId);
        if (userData == null) {
            return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
        }
        if (!userData.getTotalBattleRecordMap().containsKey(roundDay)) {
            userData.getTotalBattleRecordMap().put(roundDay, new CrossKuangBattleRecord());
        }
        for (Map.Entry<Integer, CrossKuangBattleRecord> entry : userData.getTotalBattleRecordMap().entrySet()) {
            Kuang.KuangBattlePersonReportTemp.Builder builder = Kuang.KuangBattlePersonReportTemp.newBuilder();
            builder.setKill(entry.getValue().getKill());
            builder.setKillScore(entry.getValue().getKillScore());
            builder.setSeize(entry.getValue().getSeize());
            builder.setSeizeScore(entry.getValue().getSeizeScore());
            builder.setRound(entry.getKey());
            respMsg.addPerson(builder);
        }
        // 宗门战报
        Map<Integer, Map<Integer, CrossKuangBattleCampScoreRecord>> campScoreRecordMap = crossKuangBattleData.getCampScoreRecordMap();
        // 本轮也生成一份
        if (!campScoreRecordMap.containsKey(roundDay)) {
            Map<Integer, CrossKuangBattleCampScoreRecord> recordMap = new ConcurrentHashMap<>();
            int rank = 1;
            for (int campId : campDataMap.keySet()) {
                CrossKuangBattleCampScoreRecord record = new CrossKuangBattleCampScoreRecord();
                record.setCampId(campId);
                record.setScore(0);
                record.setRank(rank++);
                recordMap.put(campId, record);
            }
            campScoreRecordMap.put(roundDay, recordMap);
        }
        for (Map.Entry<Integer, Map<Integer, CrossKuangBattleCampScoreRecord>> recordMap : campScoreRecordMap.entrySet()) {
            Kuang.KuangBattleCampReportTemp.Builder builder = Kuang.KuangBattleCampReportTemp.newBuilder();
            for (Map.Entry<Integer, CrossKuangBattleCampScoreRecord> entry : recordMap.getValue().entrySet()) {
                Kuang.KuangBattleCampScoreReportTemp.Builder report = Kuang.KuangBattleCampScoreReportTemp.newBuilder();
                report.setCampId(entry.getValue().getCampId());
                report.setScore(entry.getValue().getScore());
                report.setRank(entry.getValue().getRank());
                builder.addCamp(report);
            }
            builder.setRound(recordMap.getKey());
            respMsg.addCamp(builder);
        }
        respMsg.setRet(0);
        sendPacket(Protocol.U_KUANG_GET_BATTLE_REPORT, respMsg, userId);
        return 0;
    }

    /**
     * 标记地点
     */
    public int markPlaceByCmd(long userId, int placeId) {
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
        }
        if (!placeDataMap.containsKey(placeId)) {
            return GameErrorCode.E_KUANG_BATTLE_PLACE_NOT_FOUND;
        }
        // 阵营id
        int campId = userData.getCampId();
        // 阵营信息
        CrossKuangBattleCampData campData = getCampData(campId);
        if (userId != campData.getMajorUserId() && userId != campData.getMinorUserId()) {
            return GameErrorCode.E_KUANG_BATTLE_DONT_MARK_PLACE;
        }
        // 宗主标记
        long nowTime = System.currentTimeMillis();
        // 标记cd
        int markCd = GameConfig.KUANG_PVP_SIGN_CD;
        if (userId == campData.getMajorUserId()) {
            if (placeId == campData.getMajorPlaceId()) {
                campData.setMajorPlaceId(0);
            } else {
                if (nowTime < campData.getMajorMarkTime()) {
                    return GameErrorCode.E_KUANG_BATTLE_MARK_TIME_NO_ENOUGH;
                }
                campData.setMajorPlaceId(placeId);
                // 设置下次可标记的时间
                campData.setMajorMarkTime(nowTime + DateHelper.SECOND_MILLIONS * markCd);
                // 添加公告
                CrossKuangBattleNoticeData noticeData = new CrossKuangBattleNoticeData();
                noticeData.setCampId(campId);
                noticeData.setNoticeType(eKuangBattleNoticeType.MajorMarkPlace);
                noticeData.setContent(String.valueOf(placeId));
                noticeData.setNoticeTime(System.currentTimeMillis());
                noticeData.setIsRoll(Integer.parseInt(GameConfig.KUANG_PVP_NOTICE_SIGN));
                addNoticeData(noticeData, userId, 0);
            }
        }
        // 副宗主标记
        if (userId == campData.getMinorUserId()) {
            if (placeId == campData.getMinorPlaceId()) {
                campData.setMinorPlaceId(0);
            } else {
                if (nowTime < campData.getMinorMarkTime()) {
                    return GameErrorCode.E_KUANG_BATTLE_MARK_TIME_NO_ENOUGH;
                }
                campData.setMinorPlaceId(placeId);
                // 设置下次可标记的时间
                campData.setMinorMarkTime(nowTime + DateHelper.SECOND_MILLIONS * markCd);
                // 添加公告
                CrossKuangBattleNoticeData noticeData = new CrossKuangBattleNoticeData();
                noticeData.setCampId(campId);
                noticeData.setNoticeType(eKuangBattleNoticeType.MinorMarkPlace);
                noticeData.setContent(String.valueOf(placeId));
                noticeData.setNoticeTime(System.currentTimeMillis());
                noticeData.setIsRoll(Integer.parseInt(GameConfig.KUANG_PVP_NOTICE_SIGN));
                addNoticeData(noticeData, userId, 0);
            }
        }
        Kuang.KuangBattleMarkPlaceRespMsg.Builder respMsg = Kuang.KuangBattleMarkPlaceRespMsg.newBuilder();
        respMsg.setRet(0);
        sendPacket(ClientProtocol.U_KUANG_MARK_PLACE, respMsg, userId);
        // 同步宗门信息到本宗门的成员
        syncCampInfoToAllCampMember(campId);
        return 0;
    }

    /**
     * 任命副宗主
     * minorUserId 为 0 移除副宗主
     */
    public int appointMinorUserByCmd(long userId, long minorUserId) {
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
        }
        // 宗门id
        int campId = userData.getCampId();
        CrossKuangBattleCampData campData = getCampData(campId);
        if (campData.getMajorUserId() != userId) {
            return GameErrorCode.E_KUANG_BATTLE_NO_PERMISSION;
        }
        Kuang.KuangBattleAppointMinorUserRespMsg.Builder respMsg = Kuang.KuangBattleAppointMinorUserRespMsg.newBuilder();
        if (minorUserId == 0) {
            // 移除副宗主相关操作
            campData.setMinorPlaceId(0);
            campData.setMinorMarkTime(0);
            // 添加公告
            CrossKuangBattleNoticeData noticeData = new CrossKuangBattleNoticeData();
            noticeData.setCampId(campId);
            noticeData.setNoticeType(eKuangBattleNoticeType.CancelAppoint);
            noticeData.setContent("");
            noticeData.setNoticeTime(System.currentTimeMillis());
            noticeData.setIsRoll(Integer.parseInt(GameConfig.KUANG_PVP_NOTICE_APPOINTMENT_RECOVERY));
            addNoticeData(noticeData, userId, campData.getMinorUserId());

        } else {
            // 任命操作需要限制
            CrossKuangBattleUserData minorUser = getUserData(minorUserId);
            if (minorUser == null) {
                return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
            }
            if (minorUser.getCampId() != campId) {
                return GameErrorCode.E_KUANG_BATTLE_ONLY_APPOINT_THE_SAME_CAMP;
            }
            long nowTime = System.currentTimeMillis();
            if (nowTime < campData.getAppointTime()) {
                return GameErrorCode.E_KUANG_BATTLE_APPOINT_TIME_LIMIT;
            }
            // 获取副宗主的排行
            int minorRank = getCampUserRankByUserId(minorUserId);
            if (minorRank > GameConfig.KUANG_COMMISSION_LIMIT) {
                return GameErrorCode.E_KUANG_BATTLE_APPOINT_RANK_LIMIT;
            }
            // 任命cd
            campData.setAppointTime(nowTime + DateHelper.SECOND_MILLIONS * GameConfig.KUANG_PVP_APPOINTMENT_CD);
            // 添加公告
            CrossKuangBattleNoticeData noticeData = new CrossKuangBattleNoticeData();
            noticeData.setCampId(campId);
            noticeData.setNoticeType(eKuangBattleNoticeType.Appoint);
            noticeData.setContent("");
            noticeData.setNoticeTime(System.currentTimeMillis());
            noticeData.setIsRoll(Integer.parseInt(GameConfig.KUANG_PVP_NOTICE_APPOINTMENT));
            addNoticeData(noticeData, userId, minorUserId);
        }
        campData.setMinorUserId(minorUserId);
        respMsg.setRet(0);
        sendPacket(Protocol.U_KUANG_APPOINT_MINOR_USER, respMsg, userId);
        // 同步下数据给宗门成员
        syncCampInfoToAllCampMember(campId);
        return 0;
    }


    /**
     * 同步宗门信息到本宗门的成员
     */
    public void syncCampInfoToAllCampMember(int campId) {
        CrossKuangBattleCampData campData = getCampData(campId);
        if (campData == null) {
            return;
        }
        Kuang.KuangBattleCampSyncMsg.Builder builder = Kuang.KuangBattleCampSyncMsg.newBuilder();
        builder.setCamp(parseKuangBattleCampTemp(campData));
        Set<Long> list = getUserIdListInActivityByCampId(campId);
        sendPacketToAll(weekId, groupId, Protocol.U_KUANG_CAMP_SYNC, builder, list);
    }

    /**
     * 获取仙力宗主
     */
    public int getMajorUserByCmd(long userId) {
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
        }
        // 获取阵营
        int campId = userData.getCampId();
        Kuang.KuangBattleGetMajorUserRespMsg.Builder respMsg = Kuang.KuangBattleGetMajorUserRespMsg.newBuilder();
        respMsg.setRet(0);
        CrossKuangBattleCampData campData = getCampData(campId);
        if (campData != null) {
            // 获取宗主信息
            long majorUserId = campData.getMajorUserId();
            if (majorUserId == 0) {
                // 如果没有宗主则获取宗门最高仙力的人
                majorUserId = getCampMaxAbilityUserId(campId);
            }
            CrossKuangBattleUserData majorUserData = getUserData(majorUserId);
            if (majorUserData != null) {
                respMsg.setMajorUser(parseKuangBattleUserDetailTemp(majorUserData));
            }
        }
        // 获取一下当前的个人阵营排名
        respMsg.setMyRank(getCampUserRankByUserId(userId));
        sendPacket(ClientProtocol.U_KUANG_GET_MAJOR_USER, respMsg, userId);
        return 0;
    }

    /**
     * 获取阵营区服列表
     */
    public int getCampServerByCmd(long userId) {
        Kuang.KuangBattleGetCampServerRespMsg.Builder respMsg = Kuang.KuangBattleGetCampServerRespMsg.newBuilder();
        for (CrossKuangBattleCampData campData : campDataMap.values()) {
            Kuang.KuangBattleCampServerTemp.Builder camp = Kuang.KuangBattleCampServerTemp.newBuilder();
            for (long serverId : campData.getServerIdList()) {
                camp.addServerId(serverId);
            }
            camp.setCampId(campData.getCampId());
            respMsg.addCamp(camp);
        }
        respMsg.setRet(0);
        sendPacket(ClientProtocol.U_KUANG_GET_CAMP_SERVER, respMsg, userId);
        return 0;
    }

    /**
     * 获取结算数据
     *
     * @param userId 用户id
     */
    public int getBattleEndDataByCmd(long userId) {
        CrossKuangBattleUserData userData = getUserData(userId);
        Kuang.KuangBattleEndDataRespMsg.Builder respMsg = Kuang.KuangBattleEndDataRespMsg.newBuilder();
        if (endRecordMap.isEmpty() || !endRecordMap.containsKey(roundDay)) {
            return GameErrorCode.E_KUANG_BATTLE_NOT_END;
        }
        for (CrossKuangBattleEndRecord endRecord : endRecordMap.values()) {
            Kuang.KuangBattleEndDataTemp.Builder temp = Kuang.KuangBattleEndDataTemp.newBuilder();
            temp.setRound(endRecord.getRound());
            // 个人战绩
            temp.setBattleScore(parseKuangBattleBattleScoreTemp(userData == null ? null : userData.getRoundBattleRecord(endRecord.getRound())));
            // 宗门积分
            Map<Integer, CrossKuangBattleCampScoreRecord> recordMap = crossKuangBattleData.getCampScoreRecordMap().get(endRecord.getRound());
            if (recordMap != null) {
                for (CrossKuangBattleCampScoreRecord campScoreRecord : recordMap.values()) {
                    Kuang.KuangBattleCampScoreTemp.Builder campScoreTemp = Kuang.KuangBattleCampScoreTemp.newBuilder();
                    campScoreTemp.setCampId(campScoreRecord.getCampId());
                    campScoreTemp.setScore(campScoreRecord.getScore());
                    campScoreTemp.setRank(campScoreRecord.getRank());
                    // 宗门总积分
                    int rankNum = 0;
                    for (CrossKuangRank rank : campTotalScoreRankModel.getRankList()) {
                        ++rankNum;
                        if (campScoreRecord.getCampId() == Integer.parseInt(rank.getId())) {
                            campScoreTemp.setTotalScore(rank.getValue());
                            campScoreTemp.setTotalRank(rankNum);
                        }
                    }
                    temp.addCampScore(campScoreTemp);
                }
            }
            // 最佳表现
            Kuang.KuangBattleBestPerformanceTemp.Builder bestPerformanceTemp = Kuang.KuangBattleBestPerformanceTemp.newBuilder();
            // 最佳抢点王
            CrossKuangBattleBestRecord bestSeizeUser = endRecord.getBestSeizeUser();
            if (bestSeizeUser != null && bestSeizeUser.getUserId() != 0) {
                Kuang.KuangBattleBattleScoreUserTemp.Builder seizeUserTemp = parseKuangBattleBattleScoreUserTemp(bestSeizeUser);
                if (seizeUserTemp != null) {
                    bestPerformanceTemp.setSeize(seizeUserTemp);
                }
            }
            // 最佳击杀王
            CrossKuangBattleBestRecord bestKillUser = endRecord.getBestKillUser();
            if (bestKillUser != null && bestKillUser.getUserId() != 0) {
                Kuang.KuangBattleBattleScoreUserTemp.Builder killUserTemp = parseKuangBattleBattleScoreUserTemp(bestKillUser);
                if (killUserTemp != null) {
                    bestPerformanceTemp.setKill(killUserTemp);
                }
            }
            temp.setBestPerformance(bestPerformanceTemp);

            int campId = getCampByUserId(userId);
            // 宗门最佳表现
            Kuang.KuangBattleBestPerformanceTemp.Builder campBestPerformanceTemp = Kuang.KuangBattleBestPerformanceTemp.newBuilder();
            CrossKuangBattleBestRecord campBestSeizeUser = endRecord.getCampBestSeizeUserMap().get(campId);
            if (campBestSeizeUser != null && campBestSeizeUser.getUserId() != 0) {
                Kuang.KuangBattleBattleScoreUserTemp.Builder campSeizeUserTemp = parseKuangBattleBattleScoreUserTemp(campBestSeizeUser);
                if (campSeizeUserTemp != null) {
                    campBestPerformanceTemp.setSeize(campSeizeUserTemp);
                }
            }
            // 宗门最佳击杀王
            CrossKuangBattleBestRecord campBestKillUser = endRecord.getCampBestKillUserMap().get(campId);
            if (campBestKillUser != null && campBestKillUser.getUserId() != 0) {
                Kuang.KuangBattleBattleScoreUserTemp.Builder campKillUserTemp = parseKuangBattleBattleScoreUserTemp(campBestKillUser);
                if (campKillUserTemp != null) {
                    campBestPerformanceTemp.setKill(campKillUserTemp);
                }
            }
            temp.setCampBestPerformance(campBestPerformanceTemp);
            // 获取个人战绩
            // 排名
            int userRankNum = 0;
            long userScore = 0;
            boolean find = false;
            for (CrossKuangRank rank : userScoreRankModel.getRankList()) {
                ++userRankNum;
                if (rank.getId().equals(String.valueOf(userId))) {
                    userScore = rank.getValue();
                    find = true;
                    break;
                }
            }
            // 没找到排名为-1
            temp.setRank(find ? userRankNum : -1);
            temp.setScore(userScore);
            respMsg.addEndData(temp);
        }
        respMsg.setRet(0);
        sendPacket(ClientProtocol.U_KUANG_GET_BATTLE_END_DATA, respMsg, userId);
        return 0;
    }

    public Kuang.KuangBattleBattleScoreUserTemp.Builder parseKuangBattleBattleScoreUserTemp(CrossKuangBattleBestRecord battleBestRecord) {
        if (battleBestRecord == null) {
            return null;
        }
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(battleBestRecord.getUserId());
        if (userBaseInfo == null) {
            return null;
        }
        Kuang.KuangBattleBattleScoreUserTemp.Builder builder = Kuang.KuangBattleBattleScoreUserTemp.newBuilder();
        builder.setUserId(battleBestRecord.getUserId());
        builder.setUser(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        // 战绩
        Kuang.KuangBattleBattleScoreTemp.Builder battleScoreTemp = Kuang.KuangBattleBattleScoreTemp.newBuilder();
        battleScoreTemp.setKill(battleBestRecord.getBattleRecord().getKill());
        battleScoreTemp.setKillScore(battleBestRecord.getBattleRecord().getKillScore());
        battleScoreTemp.setSeize(battleBestRecord.getBattleRecord().getSeize());
        battleScoreTemp.setSeizeScore(battleBestRecord.getBattleRecord().getSeizeScore());
        builder.setScore(battleScoreTemp);
        // 宗门id
        builder.setCampId(battleBestRecord.getCampId());
        builder.setLikeCnt(battleBestRecord.getLikeCnt());
        return builder;
    }


    /**
     * 获取阵营最高的仙力玩家id
     */
    public long getCampMaxAbilityUserId(int campId) {
        long userId = 0;
        CrossKuangRankListModel rankListModel = campUserRankModelMap.get(campId);
        if (rankListModel != null) {
            LinkedList<CrossKuangRank> rankLinkedList = rankListModel.getRankList();
            if (!rankLinkedList.isEmpty()) {
                CrossKuangRank first = rankLinkedList.getFirst();
                userId = Long.parseLong(first.getId());
            }
        }
        return userId;
    }

    /**
     * 获取宗门排名
     */
    public int getCampUserRankByUserId(long userId) {
        int rankNum = -1;
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return rankNum;
        }
        int campId = userData.getCampId();
        CrossKuangRankListModel rankListModel = campUserRankModelMap.get(campId);
        if (rankListModel != null) {
            LinkedList<CrossKuangRank> rankLinkedList = rankListModel.getRankList();
            int num = 0;
            for (CrossKuangRank rank : rankLinkedList) {
                num++;
                if (Long.parseLong(rank.getId()) == userId) {
                    rankNum = num;
                    break;
                }
            }
        }
        return rankNum;
    }

    /**
     * 根据服务器id获取宗门id
     */
    public int getCampIdByServerId(long serverId) {
        for (CrossKuangBattleCampData campData : campDataMap.values()) {
            if (campData.getServerIdList().contains(serverId)) {
                return campData.getCampId();
            }
        }
        return 0;
    }


    /**
     * 增加击杀战绩
     *
     * @param type 1 击杀战绩 2 占领战绩
     */
    public void addBattleScore(long userId, int type, long addScore) {
//        if (isNpc(userId)) {
//            // npc不推公告，不记录战绩了
//            return;
//        }
        // 判断下活动状态时间
        if (!isBattleTime()) {
            return;
        }
        // 获取可推送档次
        long canNoticeScoreLevel = -1;
        long oldTotalScore;
        long newTotalScore;
        CrossKuangBattleUserData userData;
        synchronized (getPlayerLock(userId)) {
            userData = getUserData(userId);
            if (userData == null) {
                return;
            }
            // 首日战绩衰减
            if (roundDay == 1 && type == 1) {
                addScore = BigDecimal.valueOf(addScore).multiply(BigDecimal.valueOf(GameConfig.KUANG_FIRST_DAY_SCORE_DISCOUNT).divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN)).setScale(0, RoundingMode.UP).longValue();
            }
            oldTotalScore = userData.calcTotalScore();
            // 本条命战绩
            CrossKuangBattleRecord battleRecord = userData.getBattleRecord();
            if (type == 1) {
                battleRecord.setKill(battleRecord.getKill() + 1);
                battleRecord.setKillScore(battleRecord.getKillScore() + addScore);
                userData.getAttackScoreMap().put(roundDay, userData.getAttackScoreMap().getOrDefault(roundDay, 0L) + addScore);
            } else if (type == 2) {
                battleRecord.setSeize(battleRecord.getSeize() + 1);
                battleRecord.setSeizeScore(battleRecord.getSeizeScore() + addScore);
                userData.getSeizeScoreMap().put(roundDay, userData.getSeizeScoreMap().getOrDefault(roundDay, 0L) + addScore);
            }
            userData.setUpdateScoreTime(System.currentTimeMillis());
            userData.setBattleRecord(battleRecord);
            // 加入历史战绩,战绩
            CrossKuangBattleRecord totalBattleRecord = userData.getRoundBattleRecord(roundDay);
            if (type == 1) {
                totalBattleRecord.setKill(totalBattleRecord.getKill() + 1);
                totalBattleRecord.setKillScore(totalBattleRecord.getKillScore() + addScore);
            } else if (type == 2) {
                totalBattleRecord.setSeize(totalBattleRecord.getSeize() + 1);
                totalBattleRecord.setSeizeScore(totalBattleRecord.getSeizeScore() + addScore);
            }
            newTotalScore = userData.calcTotalScore();
        }

        // 战绩榜
        if (!isNpc(userId) && newTotalScore > 0) {
            userScoreRankModel.rankChange(new CrossKuangRank(String.valueOf(userData.getUserId()), newTotalScore, userData.getUpdateScoreTime()));
            // 通知游戏服更新condition成就
            if (userData.getRoundTotalScore(roundDay) > 0) {
                if (roundDay == 1) {
                    notifyConditionChange(userData.getUserId(), eGamePlayerEventType.KuangBattleDay1Score, userData.getRoundTotalScore(roundDay));
                } else if (roundDay == 2) {
                    notifyConditionChange(userData.getUserId(), eGamePlayerEventType.KuangBattleDay2Score, userData.getRoundTotalScore(roundDay));
                }
            }
        }

        // 判断下个人战绩是否推送
        List<String> noticeParamList = StringUtils.stringToStringList(GameConfig.KUANG_PVP_NOTICE_PERSONAL_SCORE, "\\|");
        String params = noticeParamList.get(1);
        List<Integer> paramList = StringUtils.stringToIntegerList(params, ";");
        for (int score : paramList) {
            if (score > oldTotalScore && score <= newTotalScore) {
                canNoticeScoreLevel = score;
            }
        }
        if (canNoticeScoreLevel >= 0) {
            // 添加公告
            CrossKuangBattleNoticeData noticeData = new CrossKuangBattleNoticeData();
            noticeData.setCampId(userData.getCampId());
            noticeData.setNoticeType(eKuangBattleNoticeType.TotalScore);
            noticeData.setContent(String.valueOf(canNoticeScoreLevel));
            noticeData.setNoticeTime(System.currentTimeMillis());
            noticeData.setIsRoll(Integer.parseInt(noticeParamList.get(0)));
            addNoticeData(noticeData, userData.getUserId(), 0);
        }

    }

    /**
     * 通知游戏服condition更新值
     */
    private void notifyConditionChange(long userId, eGamePlayerEventType type, long value) {
        if (type == null) {
            return;
        }
        Kuang.CrossKuangNotifyConditionRespMsg.Builder builder = Kuang.CrossKuangNotifyConditionRespMsg.newBuilder();
        builder.setUserId(userId);
        builder.setConditionType(type.getValue());
        builder.setValue(value);
        sendPacket(GameProtocol.S_KUANG_NOTIFY_CONDITION_FROM_CROSS, builder, userId);
    }



    /**
     * 获取宗门积分列表
     */
    private List<Kuang.KuangBattleCampScoreSyncTemp.Builder> getKuangCampScoreTempList() {
        List<Kuang.KuangBattleCampScoreSyncTemp.Builder> list = new ArrayList<>();
        List<CrossKuangBattleCampData> copy = new ArrayList<>(campDataMap.values());
        for (CrossKuangBattleCampData campData : copy) {
            Kuang.KuangBattleCampScoreSyncTemp.Builder temp = Kuang.KuangBattleCampScoreSyncTemp.newBuilder();
            temp.setCampId(campData.getCampId());
            temp.setScore(campData.getScore());
            list.add(temp);
        }
        return list;
    }


    /**
     * 复活逻辑
     */
    public void revive(CrossKuangBattleUserData userData) {
        // 开始复活
        userData.setReviveCnt(userData.getReviveCnt() + 1);
        // 清空buff
        userData.setBuffList(new ArrayList<>());
        // 当前血量更新下
        userData.setCurHp(userData.getMaxHp());
        // 清空本条命战绩
        userData.setBattleRecord(new CrossKuangBattleRecord());
    }

    private void updateProperty(CrossKuangBattleUserData userData, Map<eKuangAttributeType, Long> attributeMap) {
        boolean isInit = userData.getAttributeMap().isEmpty();
        // 更新战斗属性
        for (Map.Entry<eKuangAttributeType, Long> entry : attributeMap.entrySet()) {
            eKuangAttributeType type = entry.getKey();
            // 当前血量不更新
            if (type == eKuangAttributeType.AttributeEnum_CurHp) {
                continue;
            }
            userData.getAttributeMap().put(type, entry.getValue());
        }
        // 初始赋值属性
        if (isInit) {
            // 更新最大血量
            userData.setCurHp(userData.getMaxHp());
        }
        // 检查战斗属性上限
        checkAttribute(userData.getAttributeMap());
        // 检查财神技能
        checkUserSkill(userData);
        // 更新属性时间
        userData.setUpdatePropertyTime(System.currentTimeMillis());
    }

    /**
     * 检查属性值
     * 属性范围 [0,maxValue]
     *
     * @param attributeMap 属性值
     */
    public void checkAttribute(Map<eKuangAttributeType, Long> attributeMap) {
        if (config == null) {
            return;
        }
        for (Map.Entry<eKuangAttributeType, Long> entry : config.getMaxAttributeMap().entrySet()) {
            eKuangAttributeType attributeType = entry.getKey();
            Long attributeValue = entry.getValue();
            attributeMap.put(attributeType, Math.max(0, Math.min(attributeValue, attributeMap.getOrDefault(attributeType, 0L))));
        }
    }


    public Kuang.KuangBattleUserPropertyTemp.Builder parseKuangBattleUserPropertyTemp(Map<eKuangAttributeType, Long> attributeMap) {
        if (attributeMap == null) {
            return null;
        }
        Kuang.KuangBattleUserPropertyTemp.Builder builder = Kuang.KuangBattleUserPropertyTemp.newBuilder();
        for (Map.Entry<eKuangAttributeType, Long> entry : attributeMap.entrySet()) {
            // 转一下枚举
            Kuang.AttributeEnum attributeEnum = CrossKuangPb.parseAttributeEnum(entry.getKey());
            if (attributeEnum == null) {
                continue;
            }
            builder.addAttribute(CrossKuangPb.parseAttributeDataTemp(attributeEnum, entry.getValue()));
        }
        return builder;
    }

    /**
     * 某轮战绩
     */
    private Kuang.KuangBattleBattleScoreTemp.Builder parseKuangBattleBattleScoreTemp(CrossKuangBattleRecord battleRecord) {
        // 统计战报
        Kuang.KuangBattleBattleScoreTemp.Builder builder = Kuang.KuangBattleBattleScoreTemp.newBuilder();
        int kill = 0;
        long killScore = 0;
        int seize = 0;
        long seizeScore = 0;
        if (battleRecord != null) {
            kill = battleRecord.getKill();
            killScore = battleRecord.getKillScore();
            seize = battleRecord.getSeize();
            seizeScore = battleRecord.getSeizeScore();
        }
        builder.setKill(kill);
        builder.setKillScore(killScore);
        builder.setSeize(seize);
        builder.setSeizeScore(seizeScore);
        return builder;
    }


    public Kuang.KuangBattleOtherUserTemp.Builder parseKuangBattleOtherUserTemp(CrossKuangBattleUserData userData) {
        if (userData == null) {
            return null;
        }
        Kuang.KuangBattleOtherUserTemp.Builder builder = Kuang.KuangBattleOtherUserTemp.newBuilder();
        builder.setCampId(userData.getCampId());
        builder.setPlayerData(parseKuangBattlePlayerSimpleTempMsg(userData.getUserId()));
        // 这里看战斗属性就行了
        builder.setProperty(parseKuangBattleUserPropertyTemp(userData.getActualAttributeMap()));
        builder.setPlaceId(userData.getPlaceId());
        builder.setPosition(parseKuangBattlePositionTemp(userData.getPosition()));
        builder.setReviveTime(userData.getReviveTime());
        builder.setKillNum(userData.getBattleRecord().getKill());
        for (CrossKuangBattleUserBuff userBuff : userData.getBuffList()) {
            builder.addBuffList(parseKuangBattleBuffTemp(userBuff));
        }
        return builder;
    }

    private Kuang.KuangBattlePositionTemp.Builder parseKuangBattlePositionTemp(CrossKuangBattlePosition position) {
        if (position == null) {
            return null;
        }
        Kuang.KuangBattlePositionTemp.Builder builder = Kuang.KuangBattlePositionTemp.newBuilder();
        builder.setX(position.getX());
        builder.setY(position.getY());
        builder.setDirX(position.getDirX());
        builder.setDirY(position.getDirY());
        builder.setTime(position.getTime());
        return builder;
    }

    public Kuang.KuangBattlePlayerSimpleTempMsg.Builder parseKuangBattlePlayerSimpleTempMsg(long userId) {
        Kuang.KuangBattlePlayerSimpleTempMsg.Builder builder = Kuang.KuangBattlePlayerSimpleTempMsg.newBuilder();
        if (isNpc(userId)) {
            CrossKuangBattleNpcData npcData = npcDataMap.get(userId);
            builder.setDecoration(npcData.getDecoration());
            builder.setNickName(npcData.getNickName());
            builder.setUserId(userId);
            KuangMatchGroup matchGroup = CrossKuangMgr.getMatchGroup(weekId, groupId);
            if (matchGroup != null) {
                builder.setServerId(matchGroup.getServerIdList().get(randomHelper.next(0, matchGroup.getServerIdList().size())));
            } else {
                builder.setServerId(0);
            }
        } else {
            UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
            if (userBaseInfo != null) {
                builder.setDecoration(userBaseInfo.getDecoration());
                builder.setNickName(userBaseInfo.getNickName());
                builder.setServerId(userBaseInfo.getServerId());
                builder.setUserId(userId);
            }
        }
        return builder;
    }


    public Kuang.KuangBattlePlaceSeizeInfoTemp.Builder parseKuangBattlePlaceSeizeInfoTemp(CrossKuangBattlePlaceSeizeInfo seizeData, Map<Integer, Integer> campCnt) {
        if (seizeData == null) {
            return null;
        }
        Kuang.KuangBattlePlaceSeizeInfoTemp.Builder builder = Kuang.KuangBattlePlaceSeizeInfoTemp.newBuilder();
        builder.setCampId(seizeData.getCampId());
        builder.setSeizeTime(seizeData.getSeizeTime());
        // 宗门人数
        builder.setNum(campCnt.getOrDefault(seizeData.getCampId(), 0));
        return builder;
    }

    private Kuang.KuangBattleNoticeTemp.Builder parseKuangBattleNoticeTemp(CrossKuangBattleNoticeData noticeData) {
        if (noticeData == null) {
            return null;
        }
        Kuang.KuangBattleNoticeTemp.Builder builder = Kuang.KuangBattleNoticeTemp.newBuilder();
        CrossKuangBattleNoticeUserData user1 = noticeData.getUser1();
        if (user1.getUserId() != 0) {
            Kuang.KuangBattleNoticeUserTemp.Builder user1Temp = Kuang.KuangBattleNoticeUserTemp.newBuilder();
            user1Temp.setServerId(user1.getServerId());
            user1Temp.setNickName(user1.getNickName());
            user1Temp.setDecoration(user1.getDecoration());
            builder.setUser1(user1Temp);
        }
        CrossKuangBattleNoticeUserData user2 = noticeData.getUser2();
        if (user2.getUserId() != 0) {
            Kuang.KuangBattleNoticeUserTemp.Builder user2Temp = Kuang.KuangBattleNoticeUserTemp.newBuilder();
            user2Temp.setServerId(user2.getServerId());
            user2Temp.setNickName(user2.getNickName());
            user2Temp.setDecoration(user2.getDecoration());
            builder.setUser2(user2Temp);
        }
        builder.setCampId(noticeData.getCampId());
        builder.setNoticeType(noticeData.getNoticeType().getValue());
        builder.setContent(noticeData.getContent());
        builder.setNoticeTime(noticeData.getNoticeTime());
        builder.setIsRoll(noticeData.getIsRoll());
        return builder;
    }

    public Kuang.KuangBattleUserDataTemp.Builder parseKuangBattleUserDataTemp(CrossKuangBattleUserData userData) {
        if (userData == null) {
            return null;
        }
        Kuang.KuangBattleUserDataTemp.Builder builder = Kuang.KuangBattleUserDataTemp.newBuilder();
        builder.setProperty(parseKuangBattleUserPropertyTemp(userData.getActualAttributeMap()));
        builder.setCampId(userData.getCampId());
        builder.setPlaceId(userData.getPlaceId());
        builder.setTransferTime(userData.getTransferTime());
        builder.setAttackTime(userData.getAttackTime());
        builder.setAttackedTime(userData.getAttackedTime());
        builder.setReviveTime(userData.getReviveTime());
        builder.setKillNum(userData.getBattleRecord().getKill());
        for (CrossKuangBattleUserBuff userBuff : userData.getBuffList()) {
            builder.addBuffList(parseKuangBattleBuffTemp(userBuff));
        }
        for (CrossKuangBattleUserSkill userSkill : userData.getSkillList()) {
            builder.addSkillList(parseKuangBattleSkillTemp(userSkill));
        }
        return builder;
    }

    private Kuang.KuangBattleUserBuffTemp.Builder parseKuangBattleBuffTemp(CrossKuangBattleUserBuff userBuff) {
        if (userBuff == null) {
            return null;
        }
        Kuang.KuangBattleUserBuffTemp.Builder builder = Kuang.KuangBattleUserBuffTemp.newBuilder();
        // 转一下枚举
        Kuang.AttributeEnum attributeEnum = CrossKuangPb.parseAttributeEnum(userBuff.getType());
        if (attributeEnum == null) {
            return null;
        }
        builder.setAttribute(CrossKuangPb.parseAttributeDataTemp(attributeEnum, userBuff.getValue()));
        builder.setExpireTime(userBuff.getExpireTime());
        return builder;
    }

    private Kuang.KuangBattleUserSkillTemp.Builder parseKuangBattleSkillTemp(CrossKuangBattleUserSkill userSkill) {
        if (userSkill == null) {
            return null;
        }
        Kuang.KuangBattleUserSkillTemp.Builder builder = Kuang.KuangBattleUserSkillTemp.newBuilder();
        builder.setType(userSkill.getType());
        builder.setLittleType(userSkill.getLittleType());
        builder.setReadyTime(userSkill.getReadyTime());
        return builder;
    }

    public Kuang.KuangBattleCampTemp.Builder parseKuangBattleCampTemp(CrossKuangBattleCampData campData) {
        if (campData == null) {
            return null;
        }
        Kuang.KuangBattleCampTemp.Builder builder = Kuang.KuangBattleCampTemp.newBuilder();
        builder.setCampId(campData.getCampId());
        // 宗主信息
        if (campData.getMajorUserId() != 0) {
            CrossKuangBattleUserData majorUser = getUserData(campData.getMajorUserId());
            if (majorUser != null) {
                builder.setMajorUser(parseKuangBattleUserDetailTemp(majorUser));
            }
        }
        // 副宗主信息
        if (campData.getMinorUserId() != 0) {
            CrossKuangBattleUserData minorUser = getUserData(campData.getMinorUserId());
            if (minorUser != null) {
                builder.setMinorUser(parseKuangBattleUserDetailTemp(minorUser));
            }
        }
        builder.setMajorPlaceId(campData.getMajorPlaceId());
        builder.setMinorPlaceId(campData.getMinorPlaceId());
        builder.setAppointTime(campData.getAppointTime());
        builder.setMajorMarkTime(campData.getMajorMarkTime());
        builder.setMinorMarkTime(campData.getMinorMarkTime());
        return builder;
    }


    public Kuang.KuangBattleUserDetailTemp.Builder parseKuangBattleUserDetailTemp(CrossKuangBattleUserData userData) {
        if (userData == null) {
            return null;
        }
        Kuang.KuangBattleUserDetailTemp.Builder builder = Kuang.KuangBattleUserDetailTemp.newBuilder();
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userData.getUserId());
        if (userBaseInfo == null) {
            return null;
        }
        builder.setUserId(userData.getUserId());
        builder.setUser(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        builder.setProperty(parseKuangBattleUserPropertyTemp(userData.getActualAttributeMap()));
        return builder;
    }

    public Kuang.KuangBattlePlaceInfoTemp.Builder parseKuangBattlePlaceInfoTemp(CrossKuangBattlePlaceData placeData) {
        if (placeData == null) {
            return null;
        }
        Kuang.KuangBattlePlaceInfoTemp.Builder builder = Kuang.KuangBattlePlaceInfoTemp.newBuilder();
        builder.setPlaceId(placeData.getPlaceId());
        // 组装房间玩家信息

        for (Long userId : getMemUserList(placeData.getPlaceId())) {
            CrossKuangBattleUserData userData = getUserData(userId);
            if (userData == null) {
                continue;
            }
            if (!isBirthPlace(placeData.getPlaceId()) && userData.getUserState() == 1) {
                continue;
            }
            builder.addUser(parseKuangBattleOtherUserTemp(userData));
        }
        builder.setCampId(placeData.getCampId());
        builder.setSeizeTime(placeData.getSeizeTime());
        return builder;
    }

    private Kuang.KuangBattleAttackedTemp.Builder parseKuangBattleAttackedTemp(CrossKuangBattleAttackHelper attackHelper) {
        Kuang.KuangBattleAttackedTemp.Builder builder = Kuang.KuangBattleAttackedTemp.newBuilder();
        builder.setAttackUserId(attackHelper.getAttackUserId());
        builder.setAttackedUserId(attackHelper.getAttackedUserId());
        builder.setHp(attackHelper.getHp());
        builder.setSuckHp(attackHelper.getSuckHp());
        builder.setIsCrit(attackHelper.isCrit());
        builder.setIsDodge(attackHelper.isDodge());
        builder.setAttackHp(attackHelper.getAttackHp());
        builder.setAttackedHp(attackHelper.getAttackedHp());
        builder.setKillNum(attackHelper.getKillNum());
        return builder;
    }

    /**
     * 积分同步给活动中的人
     */
    public void campScoreSyncTask() {
        if (!needSyncCampScore) {
            return;
        }
        if (!isOpenTime()) {
            return;
        }
        Kuang.KuangBattleCampScoreSyncMsg.Builder builder = Kuang.KuangBattleCampScoreSyncMsg.newBuilder();
        List<Kuang.KuangBattleCampScoreSyncTemp.Builder> list = getKuangCampScoreTempList();
        for (Kuang.KuangBattleCampScoreSyncTemp.Builder temp : list) {
            builder.addCampScore(temp);
        }
        sendPacketToAll(weekId, groupId, Protocol.U_KUANG_CAMP_SCORE_SYNC, builder, inBattleUserSet);
        needSyncCampScore = false;
    }

    /**
     * 检测房间用户心跳
     */
    public void checkPlacePingTask() {
        long nowTime = System.currentTimeMillis();
        if (!isOpenTime()) {
            return;
        }
        Set<Long> needKickUser = new HashSet<>();
        for (Integer placeId : placeDataMap.keySet()) {
            for (Long userId : getMemUserList(placeId)) {
                CrossKuangBattleUserData userData = getUserData(userId);
                if (userData == null) {
                    continue;
                }
                // npc 不处理
                if (isNpc(userId)) {
                    continue;
                }
                // 出生点就不处理了
                if (isBirthPlace(placeId)) {
                    continue;
                }
                // 存活的超过10秒没发包踢出去，死亡的1分钟
                if (userData.getUserState() == 0) {
                    if (nowTime - userData.getLastPingPlaceTime() > DateHelper.SECOND_MILLIONS * 10) {
                        needKickUser.add(userId);
                    }
                } else {
                    if (nowTime - userData.getLastPingPlaceTime() > DateHelper.MINUTE_MILLIONS) {
                        needKickUser.add(userId);
                    }
                }

            }
        }
        for (Long userId : needKickUser) {
            CrossKuangBattleUserData userData = getUserData(userId);
            if (userData != null) {
                leavePlace(userData, eKuangBattleLeaveType.KickOut);
            }
        }
    }

    /**
     * npc行为定时器
     */
    public void npcActionTask() {
        if (!isBattleTime()) {
            return;
        }
        npcAttackTask();
        npcReviveTask();
    }

    /**
     * npc攻击
     */
    public void npcAttackTask() {
        if (!npcAttack) {
            return;
        }
        // 攻击事件
        for (Integer placeId : placeDataMap.keySet()) {
            Set<Long> memUserList = getMemUserList(placeId);
            for (Long userId : memUserList) {
                // 这边只处理npc
                if (!isNpc(userId)) {
                    continue;
                }
                CrossKuangBattleUserData userData = getUserData(userId);
                if (userData == null) {
                    continue;
                }
                Map<eKuangAttributeType, Long> attributeMap = userData.getActualAttributeMap();
                // 攻速
                long atkSpeed = attributeMap.getOrDefault(eKuangAttributeType.AttributeEnum_AttackSpeed, 1000L);
                // 攻速千分比 区间只能1-1000  程序做个保护
                int speedRatio = Math.max(1, Math.min(1000, GameConfig.KUANG_PVP_ATTACK_SPEED_RATIO));
                // 算下一秒攻击多少下  最低0.5,最大5下，特殊处理下 程序做个保护
                double atkCount = Math.min(5, Math.max(0.5, BigDecimal.valueOf(atkSpeed).divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).multiply(BigDecimal.valueOf(speedRatio)).divide(BigDecimal.valueOf(1000), 8, RoundingMode.DOWN).doubleValue()));
                // 攻击间隔
                long atkTime = BigDecimal.valueOf(1000).divide(BigDecimal.valueOf(atkCount), 0, RoundingMode.UP).longValue();
                if (System.currentTimeMillis() < userData.getAttackTime() + atkTime) {
                    continue;
                }
                long targetUserId = randomGetOtherCampUser(new ArrayList<>(memUserList), userId);
                if (targetUserId != 0) {
                    attackByCmd(userId, targetUserId);
                }
            }
        }
    }

    /**
     * npc复活
     */
    public void npcReviveTask() {
        if (!isBattleTime()) {
            return;
        }
        if (!npcRevive) {
            return;
        }
        long nowTime = System.currentTimeMillis();
        // 复活机器人进入房间
        int randomPlaceId = getRandomPlaceId(true);
        for (Long npcId : npcUserMap.keySet()) {
            synchronized (getPlayerLock(npcId)) {
                CrossKuangBattleUserData userData = npcUserMap.get(npcId);
                CrossKuangBattleNpcData npcData = npcDataMap.get(npcId);
                if (userData == null || npcData == null) {
                    continue;
                }
                if (userData.getPlaceId() == 0 || isBirthPlace(userData.getPlaceId())) {
                    // 没到复活时间
                    if (nowTime < userData.getReviveTime()) {
                        continue;
                    }
                    // 复活
                    revive(userData);
                    // 离开旧房间
                    leavePlace(userData, eKuangBattleLeaveType.Transfer);
                    // 随机加入房间
                    joinPlace(randomPlaceId, userData);
                    userData.setTransferTime(nowTime + DateHelper.SECOND_MILLIONS * GameConfig.KUANG_PVP_DELIVERY_CD);
                } else {
                    if (nowTime > userData.getTransferTime() && nowTime > userData.getAttackTime() + DateHelper.SECOND_MILLIONS * 10) {
                        // 离开旧房间
                        leavePlace(userData, eKuangBattleLeaveType.Transfer);
                        // 随机加入房间
                        joinPlace(randomPlaceId, userData);
                        userData.setTransferTime(nowTime + DateHelper.SECOND_MILLIONS * GameConfig.KUANG_PVP_DELIVERY_CD);
                    }
                }
            }
        }
    }

    /**
     * 随机获取一个宝地
     */
    public int getRandomPlaceId(boolean excludeBirth) {
        List<Integer> placeIdList = new ArrayList<>();
        for (KuangPlaceConfig placeConfig : config.getPlaceConfigMap().values()) {
            if (excludeBirth && placeConfig.getType() != eKuangBattlePlaceType.Place.getValue()) {
                continue;
            }
            placeIdList.add(placeConfig.getId());
        }
        if (placeIdList.size() == 0) {
            return -1;
        }
        return placeIdList.get(randomHelper.next(0, placeIdList.size()));
    }


    private long randomGetOtherCampUser(List<Long> list, long userId) {
        List<Long> randomList = new ArrayList<>();
        int myCampId = getCampByUserId(userId);
        for (Long id : list) {
            if (id == userId) {
                continue;
            }
            if (getCampByUserId(id) == myCampId) {
                continue;
            }
            randomList.add(id);
        }
        if (randomList.size() == 0) {
            return 0;
        }
        return randomList.get(randomHelper.next(0, randomList.size()));
    }

    /**
     * 获取用户的阵营
     */
    public int getCampByUserId(long userId) {
        CrossKuangBattleUserData userData = getUserData(userId);
        return userData != null ?
                userData.getCampId()
                : getCampIdByServerId(CrossUserMgr.getServerIdByUserId(userId));
    }


    /**
     * 宝地占点产出
     */
    public void placeSeizeProduceTask() {
        long nowTime = System.currentTimeMillis();
        if (!isBattleTime()) {
            return;
        }
        Map<Integer, Long> campScoreMap = new ConcurrentHashMap<>();
        for (CrossKuangBattlePlaceData placeData : placeDataMap.values()) {
            for (CrossKuangBattlePlaceSeizeInfo seizeInfo : placeData.getSeizeInfoMap().values()) {
                if (seizeInfo.getCampId() == placeData.getCampId()) {
                    // 计算产出
                    long seizeProduce = seizeProduce(placeData);
                    campScoreMap.put(seizeInfo.getCampId(), campScoreMap.getOrDefault(seizeInfo.getCampId(), 0L) + seizeProduce);
                    int oldNoticeTime = Math.max(0, (int) ((placeData.getLastNoticeSeizeTime() - placeData.getSeizeTime()) / 1000));
                    // 检测持续占领时间
                    int seizeTime = Math.max(0, (int) ((nowTime - placeData.getSeizeTime()) / 1000));
                    // 判断下击杀是否满足推送公告
                    List<String> noticeParamList = StringUtils.stringToStringList(GameConfig.KUANG_PVP_NOTICE_PLACE_LEVEL_TIME, "\\|");
                    String params = noticeParamList.get(2);
                    List<Integer> paramList = StringUtils.stringToIntegerList(params, ";");
                    int canNoticeTime = -1;
                    for (int noticeTime : paramList) {
                        if (noticeTime > oldNoticeTime && noticeTime <= seizeTime) {
                            canNoticeTime = noticeTime;
                        }
                    }
                    if (config.getPlaceConfigMap().get(placeData.getPlaceId()).getLevel() >= Integer.parseInt(noticeParamList.get(1)) && canNoticeTime >= 0) {
                        // 添加公告
                        CrossKuangBattleNoticeData noticeData = new CrossKuangBattleNoticeData();
                        noticeData.setCampId(seizeInfo.getCampId());
                        noticeData.setNoticeType(eKuangBattleNoticeType.SeizeTime);
                        noticeData.setContent(placeData.getPlaceId() + "#" + canNoticeTime);
                        noticeData.setNoticeTime(nowTime);
                        noticeData.setIsRoll(Integer.parseInt(noticeParamList.get(0)));
                        addNoticeData(noticeData, 0, 0);
                        placeData.setLastNoticeSeizeTime(nowTime);
                    }
                }
            }
        }
        // 加积分
        for (Map.Entry<Integer, Long> entry : campScoreMap.entrySet()) {
            addCampScore(entry.getKey(), entry.getValue());
        }
    }

    /**
     * 抢占宝地定时任务
     */
    public void seizePlaceTask() {
        // 活动进行中才处理
        if (!isBattleTime()) {
            return;
        }
        for (int placeId : placeDataMap.keySet()) {
            // 定时器不需要同步
            checkPlaceSeizeTime(placeId, false);
        }
    }

    /**
     * 挨打同步
     */
    public void attackSyncTask() {
        if (!isBattleTime()) {
            return;
        }
        for (int placeId : placeDataMap.keySet()) {
            syncPlaceAttack(placeId);
        }
    }

    /**
     * 同步房间被打记录
     */
    private void syncPlaceAttack(int placeId) {
        Kuang.KuangBattleAttackedSyncMsg.Builder attackedSyncMsg = Kuang.KuangBattleAttackedSyncMsg.newBuilder();
        synchronized (attackSyncListMap) {
            if (!attackSyncListMap.containsKey(placeId)) {
                return;
            }
            List<CrossKuangBattleAttackHelper> attackList = attackSyncListMap.get(placeId);
            if (attackList.size() == 0) {
                return;
            }
            for (CrossKuangBattleAttackHelper helper : attackList) {
                attackedSyncMsg.addAttack(parseKuangBattleAttackedTemp(helper));
            }
            // 清空记录
            attackSyncListMap.put(placeId, new ArrayList<>());
        }
        // 同步给房间的用户
        sendPacketToAll(weekId, groupId, Protocol.U_KUANG_SYNC_ATTACKED, attackedSyncMsg, getMemUserList(placeId));
    }

    public void checkCampMajorTask() {
        if (!isOpenTime()) {
            return;
        }
        // 确定宗主
        for (CrossKuangBattleCampData campData : campDataMap.values()) {
            // 已有宗主不处理
            if (campData.getMajorUserId() != 0) {
                continue;
            }
            // 获取榜单第一
            long maxAbilityUserId = getCampMaxAbilityUserId(campData.getCampId());
            campData.setMajorUserId(maxAbilityUserId);
            // 同步
            syncCampInfoToAllCampMember(campData.getCampId());
        }
    }


    /**
     * 同步房间内的用户数据
     */
    public void placeUserDataSyncTask() {
        if (!isOpenTime()) {
            return;
        }
        for (Integer placeId : placeDataMap.keySet()) {
            Set<Long> userList = getMemUserList(placeId);
            if (userList.size() == 0) {
                // 没有用户就不需要同步了
                continue;
            }
            // 同步用户给房间内的用户
            Kuang.KuangBattlePlaceSyncMsg.Builder builder = Kuang.KuangBattlePlaceSyncMsg.newBuilder();
            for (Long userId : userList) {
                CrossKuangBattleUserData userData = getUserData(userId);
                if (userData == null) {
                    continue;
                }
                if (!isBirthPlace(placeId) && userData.getUserState() == 1) {
                    continue;
                }
                Kuang.KuangBattleSimpleUserTemp.Builder userTemp = Kuang.KuangBattleSimpleUserTemp.newBuilder();
                userTemp.setUserId(userId);
                userTemp.setPosition(parseKuangBattlePositionTemp(userData.getPosition()));
                builder.addUser(userTemp);
            }
            sendPacketToAll(weekId, groupId, Protocol.U_KUANG_SYNC_PLACE, builder, userList);
        }
    }

    public int getRoundDay() {
        int roundDay = 0;
        long nowTime = System.currentTimeMillis();
        if (nowTime >= config.getTimeConfig().getDay1BeginTime()) {
            roundDay = 1;
        }
        if (nowTime >= config.getTimeConfig().getDay2BeginTime()) {
            roundDay = 2;
        }
        return roundDay;
    }

    /**
     * 活动时间检测
     */
    public void checkActivityTimeTask() {
        long nowTime = System.currentTimeMillis();
        boolean needSync = false;
        synchronized (lock) {
            int roundDay = getRoundDay();
            if (roundDay == 0) {
                return;
            }
            if (this.roundDay != roundDay) {
                // 切换轮次
                this.roundDay = roundDay;
                crossKuangBattleData.setRound(roundDay);
                // 重置房间数据
                resetPlaceData();
                // 重置宗门相关数据
                resetCampData();
                // 重置用户数据
                resetUserData();
                // 清除公告
                noticeDataList.clear();
                for (LinkedList<CrossKuangBattleNoticeData> linkedList : campNoticeDataMap.values()) {
                    linkedList.clear();
                }
                battleEnd = false;
                needSync = true;
            }
            // 检查活动是否结束
            if (checkActivityEnd()) {
                battleEnd = true;
                activityEndSync();
            }
        }
        if (needSync) {
            // 同步所有人活动状态
            for (Long userId : userDataMap.keySet()) {
                crossBattleSync(userId);
            }
        }
        // 检测下结束公告
        List<String> noticeParamList = StringUtils.stringToStringList(GameConfig.KUANG_PVP_NOTICE_BATTLE_END_TIME, "\\|");
        String params = noticeParamList.get(1);
        List<Integer> paramList = StringUtils.stringToIntegerList(params, ";");
        // updateTime 差值判断
        long oldTimeOffset = (config.getBattleEndTime(roundDay) - crossKuangBattleData.getUpdateTime()) / 1000;
        long newTimeOffset = (config.getBattleEndTime(roundDay) - nowTime) / 1000;
        long noticeTime = -1;
        for (int time : paramList) {
            if (oldTimeOffset > time && time >= newTimeOffset) {
                noticeTime = time;
            }
        }
        if (noticeTime > 0) {
            // 添加公告
            CrossKuangBattleNoticeData noticeData = new CrossKuangBattleNoticeData();
            noticeData.setCampId(0);
            noticeData.setNoticeType(eKuangBattleNoticeType.PvpTimeEnd);
            noticeData.setContent(String.valueOf(noticeTime / 60));
            noticeData.setNoticeTime(nowTime);
            noticeData.setIsRoll(Integer.parseInt(noticeParamList.get(0)));
            addNoticeData(noticeData, 0, 0);
        }
        crossKuangBattleData.setUpdateTime(System.currentTimeMillis());

        if (nowTime >= config.getTimeConfig().getDay2BattleEndTime() && !crossKuangBattleData.isBattleEndHandle()) {
            // 到了领奖期，记录下榜单数据
            crossKuangBattleData.setBattleEndHandle(true);
            // 个人榜单
            int num = 0;
            for (CrossKuangRank rank : userScoreRankModel.getRankList()) {
                num++;
                // 加个日志
                CrossAutoLogMgr.add(new LogKuangBattleRank(weekId, groupId, Long.parseLong(rank.getId()), 1, num, rank.getValue(), new Date(rank.getTime())));
            }
            // 阵营榜单
            num = 0;
            for (CrossKuangRank rank : campTotalScoreRankModel.getRankList()) {
                num++;
                // 加个日志
                CrossAutoLogMgr.add(new LogKuangBattleRank(weekId, groupId, Long.parseLong(rank.getId()), 2, num, rank.getValue(), new Date(rank.getTime())));
            }
        }
    }

    private void resetUserData() {
        for (CrossKuangBattleUserData userData : userDataMap.values()) {
            userData.setPlaceId(0);
            userData.setBattleRecord(new CrossKuangBattleRecord());
            userData.setReviveCnt(0);
            userData.setBuffList(new ArrayList<>());
            // 切换轮次,血量回复
            userData.setCurHp(userData.getMaxHp());
        }
    }

    private void resetCampData() {
        for (CrossKuangBattleCampData campData : campDataMap.values()) {
            campData.setScore(0);
            campData.setMajorUserId(0);
            campData.setMajorPlaceId(0);
            campData.setMinorUserId(0);
            campData.setMinorPlaceId(0);
            campData.setMajorMarkTime(0);
            campData.setMinorMarkTime(0);
            campData.setUpdateScoreTime(System.currentTimeMillis());
            // 更新下本轮宗门积分榜单
            campScoreRankModel.rankChange(new CrossKuangRank(String.valueOf(campData.getCampId()), campData.getScore(), campData.getUpdateScoreTime()));
        }
    }


    /**
     * 空任务事件,10秒一次
     */
    public void crossKuangEmptyTask() {
        if (Config.isDebug()) {
            logger.info("crossKuangEmptyTask");
        }
    }

    /**
     * 离线处理
     */
    public void offLineByCmd(long userId) {
        // 离开活动
        leaveBattleByCmd(userId);
    }

    /**
     * 同步下活动状态
     */
    public void crossBattleSync(long userId) {
        CrossKuangBattleUserData userData = getUserData(userId);
        Kuang.CrossKuangLoginRespMsg.Builder respMsg = Kuang.CrossKuangLoginRespMsg.newBuilder();
        respMsg.setWeekId(weekId);
        respMsg.setGroupId(groupId);
        respMsg.setCampId(getCampByUserId(userId));
        respMsg.setRoundDay(roundDay);
        respMsg.setBattleEnd(battleEnd);
        respMsg.setFirstRoundScore(userData == null ? 0 : userData.getRoundTotalScore(1));
        respMsg.setPersonRankReward(userData != null && userData.isPersonRankReward());
        respMsg.setGroupRankReward(userData != null && userData.isGroupRankReward());
        respMsg.setEnterBattle(userData != null && userData.isEnterBattle());
        sendPacket(Protocol.S_KUANG_CROSS_LOGIN_SYNC, respMsg, userId);
    }



    public void testCode(long userId, String code, String param) {
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return;
        }
        // 宗门id
        int campId = userData.getCampId();
        if ("/kssx".equals(code)) {
            String[] split = param.split("#");
            eKuangAttributeType type = com.yanqu.road.entity.enums.kuang.eKuangAttributeType.forValue(Integer.parseInt(split[0]));
            if (type == null) {
                return;
            }
            userData.getAttributeMap().put(type, Long.valueOf(split[1]));
            userData.setCurHp(userData.getMaxHp());
        }
        // 设置宗主
        if ("/kszz".equals(code)) {
            CrossKuangBattleCampData campData = getCampData(campId);
            campData.setMajorUserId(userId);
            if (campData.getMinorUserId() == userId) {
                campData.setMinorUserId(0);
            }
            syncCampInfoToAllCampMember(campId);
        }
        // 更改宗门
        if ("/ksgzm".equals(code)) {
            userData.setCampId(Integer.parseInt(param));
        }
        // 重置积分
        if ("/ksczjf".equals(code)) {
            for (int id : campDataMap.keySet()) {
                CrossKuangBattleCampData campData = getCampData(id);
                addCampScore(id, -campData.getScore());
            }
            battleEnd = false;
            endRecordMap.remove(roundDay);
            crossBattleSync(userId);
        }
        // npc开启攻击
        if ("/kskqgj".equals(code)) {
            npcAttack = true;
        }
        // npc取消攻击
        if ("/ksqxgj".equals(code)) {
            npcAttack = false;
        }
        // npc开启复活
        if ("/kskqfh".equals(code)) {
            npcRevive = true;
        }
        // npc取消复活
        if ("/ksqxfh".equals(code)) {
            npcRevive = false;
        }
        // 踢出指定房间所有npc
        if ("/kstnpc".equals(code)) {
            int placeId = Integer.parseInt(param);
            synchronized (getPlaceLock(placeId)) {
                Set<Long> userList = getMemUserList(placeId);
                for (Long id : userList) {
                    if (!isNpc(id)) {
                        continue;
                    }
                    leavePlace(getUserData(id), eKuangBattleLeaveType.KickOut);
                    synchronized (npcDataMap) {
                        npcDataMap.remove(id);
                    }
                    synchronized (npcUserMap) {
                        npcUserMap.remove(id);
                    }
                }
            }
        }
        // 踢出所有npc
        if ("/kstallnpc".equals(code)) {
            for (int placeId = 1; placeId <= 18; placeId++) {
                synchronized (getPlaceLock(placeId)) {
                    Set<Long> userList = getMemUserList(placeId);
                    for (Long id : userList) {
                        if (!isNpc(id)) {
                            continue;
                        }
                        leavePlace(getUserData(id), eKuangBattleLeaveType.KickOut);
                        removeNpc(id);
                    }
                }
            }
        }
        // 杀死所有npc
        if ("/kskallnpc".equals(code)) {
            for (int placeId = 5; placeId <= 18; placeId++) {
                synchronized (getPlaceLock(placeId)) {
                    Set<Long> userList = getMemUserList(placeId);
                    for (Long id : userList) {
                        if (!isNpc(id)) {
                            continue;
                        }
                        CrossKuangBattleUserData targetUserData = getUserData(id);
                        if (targetUserData != null) {
                            leavePlace(targetUserData, eKuangBattleLeaveType.KickOut);
                            joinPlace(targetUserData.getCampId(), targetUserData);
                        }
                    }
                }
            }
        }
        // 增加某个宗门xxx积分
        if ("/ksjjf".equals(code)) {
            String[] split = param.split("#");
            addCampScore(Integer.parseInt(split[0]), Long.parseLong(split[1]));
        }
        if ("/kssjnpc".equals(code)) {
            int count = Integer.parseInt(param);
            for (int i = 0; i < count; i++) {
                int placeId = randomHelper.next(5, 19);
                int canJoinCamp = getCanJoinCamp(placeId);
                if (canJoinCamp == 0) {
                    continue;
                }
                StringBuilder sb = new StringBuilder();
                sb.append(randomHelper.next(1, 1000)).append("|")
                        .append(randomHelper.next(1, 100)).append("|")
                        .append(randomHelper.next(1, 1000)).append("|")
                        .append(randomHelper.next(1, 1000)).append("|")
                        .append(randomHelper.next(1000, 5000)).append("|")
                        .append(randomHelper.next(1, 1000)).append("|")
                        .append(randomHelper.next(1, 1000)).append("|")
                        .append(randomHelper.next(1, 1000)).append("|")
                        .append(randomHelper.next(1, 1000)).append("|");
                CrossKuangBattleUserData npcUserData = genNpcUserData(canJoinCamp, sb.toString());
                // 加入房间
                joinPlace(placeId, npcUserData);
            }
        }
        if ("/ksnpc1".equals(code)) {
            String[] split = param.split("#");
            int count = Integer.parseInt(split[0]);
            for (int i = 0; i < count; i++) {
                int placeId = randomHelper.next(5, 19);
                int canJoinCamp = getCanJoinCamp(placeId);
                if (canJoinCamp == 0) {
                    continue;
                }
                CrossKuangBattleUserData npcUserData = genNpcUserData(canJoinCamp, split[1]);
                // 加入房间
                joinPlace(placeId, npcUserData);
            }
        }
        if ("/ksnpc2".equals(code)) {
            String[] split = param.split("#");
            int count = Integer.parseInt(split[0]);
            int placeId = Integer.parseInt(split[1]);
            for (int i = 0; i < count; i++) {
                int canJoinCamp = getCanJoinCamp(placeId);
                if (canJoinCamp == 0) {
                    break;
                }
                CrossKuangBattleUserData npcUserData = genNpcUserData(canJoinCamp, split[2]);
                // 加入房间
                joinPlace(placeId, npcUserData);
            }
        }
        if ("/ksnpc3".equals(code)) {
            String[] split = param.split("#");
            int count = Integer.parseInt(split[0]);
            for (int i = 0; i < count; i++) {
                int placeId = randomHelper.next(5, 19);
                CrossKuangBattleUserData npcUserData = genNpcUserData(Integer.parseInt(split[1]), split[2]);
                // 加入房间
                joinPlace(placeId, npcUserData);
            }
        }
        if ("/ksnpc4".equals(code)) {
            String[] split = param.split("#");
            int count = Integer.parseInt(split[0]);
            int placeId = Integer.parseInt(split[1]);
            int genCampId = Integer.parseInt(split[2]);
            for (int i = 0; i < count; i++) {
                CrossKuangBattleUserData npcUserData = genNpcUserData(genCampId, split[3]);
                // 加入房间
                joinPlace(placeId, npcUserData);
            }
        }
        // 清空公告
        if ("/ksqkgg".equals(code)) {
            noticeDataList.clear();
            for (LinkedList<CrossKuangBattleNoticeData> list : campNoticeDataMap.values()) {
                list.clear();
            }
        }
        // 重置宝地
        if ("/ksczbd".equals(code)) {
            resetPlaceData();
        }
    }

    /**
     * 生成npc数据
     */
    private CrossKuangBattleUserData genNpcUserData(int campId, String param) {
        CrossKuangBattleUserData npc = new CrossKuangBattleUserData();
        npc.setWeekId(weekId);
        npc.setGroupId(groupId);
        npc.setUserId(npcId.incrementAndGet());
        // 宗门id
        npc.setCampId(campId);
        // 出生地id
        npc.setPlaceId(0);
        // 可传送时间
        npc.setTransferTime(System.currentTimeMillis());
        // 可复活时间
        npc.setReviveTime(System.currentTimeMillis());
        // 生命标识
        npc.setReviveCnt(0);
        // 造一份假属性
        List<Long> paramList = StringUtils.stringToLongList(param, "\\|");
        Map<eKuangAttributeType, Long> attrMap = new HashMap<>();
        attrMap.put(eKuangAttributeType.AttributeEnum_Hp, paramList.get(0));
        attrMap.put(eKuangAttributeType.AttributeEnum_Attack, paramList.get(1));
        attrMap.put(eKuangAttributeType.AttributeEnum_Critical, paramList.get(2));
        attrMap.put(eKuangAttributeType.AttributeEnum_Toughness, paramList.get(3));
        attrMap.put(eKuangAttributeType.AttributeEnum_AttackSpeed, paramList.get(4));
        attrMap.put(eKuangAttributeType.AttributeEnum_Dodge, paramList.get(5));
        attrMap.put(eKuangAttributeType.AttributeEnum_Hit, paramList.get(6));
        attrMap.put(eKuangAttributeType.AttributeEnum_LifeSteal, paramList.get(7));
        updateProperty(npc, attrMap);
        npcUserMap.put(npcId.get(), npc);
        // 顺便生成一下信息
        CrossKuangBattleNpcData dataHelper = new CrossKuangBattleNpcData();
        dataHelper.setUserId(npcId.get());
        List<Long> serverList = new ArrayList<>(getCampData(npc.getCampId()).getServerIdList());
        dataHelper.setServerId(serverList.get(randomHelper.next(0, serverList.size())));
        dataHelper.setNickName("人机" + npcId.get());
        dataHelper.setDecoration(String.valueOf(randomGetNpcHeadId()));
        npcDataMap.put(npcId.get(), dataHelper);
        return npc;
    }

    private int randomGetNpcHeadId() {
        List<Integer> list = new ArrayList<>();
        for (int i = 106055; i <= 106074; i++) {
            list.add(i);
        }
        return list.get(randomHelper.next(0, list.size()));
    }


    private int getCanJoinCamp(int placeId) {
        // 所有宗门人数计数
        CrossKuangBattlePlaceData placeData = getPlaceData(placeId);
        if (placeData == null) {
            return 0;
        }
        Map<Integer, Integer> campCntMap = new HashMap<>();
        // 初始化下
        for (int campId : campDataMap.keySet()) {
            campCntMap.put(campId, 0);
        }
        Set<Long> userList = getMemUserList(placeId);
        for (Long userId : userList) {
            CrossKuangBattleUserData userData = getUserData(userId);
            if (userData == null || userData.getUserState() == 1) {
                continue;
            }
            campCntMap.put(userData.getCampId(), campCntMap.get(userData.getCampId()) + 1);
        }
        List<Integer> ansList = new ArrayList<>();
        for (Map.Entry<Integer, Integer> entry : campCntMap.entrySet()) {
            if (entry.getValue() < GameConfig.KUANG_PVP_ROOM_PEOPLE_NUM_MAX) {
                ansList.add(entry.getKey());
            }
        }
        if (ansList.size() == 0) {
            return 0;
        }
        return ansList.get(randomHelper.next(0, ansList.size()));
    }

    /**
     * 重置房间数据
     */
    public void resetPlaceData() {
        for (CrossKuangBattlePlaceData placeData : placeDataMap.values()) {
            KuangPlaceConfig placeConfig = config.getPlaceConfigMap().get(placeData.getPlaceId());
            memUserMap.remove(placeData.getPlaceId());
            // 出生点不处理
            if (placeConfig.getType() != eKuangBattlePlaceType.Place.getValue()) {
                continue;
            }
            for (Map.Entry<Integer, CrossKuangBattlePlaceSeizeInfo> entry : placeData.getSeizeInfoMap().entrySet()) {
                entry.getValue().setCampId(entry.getKey());
                entry.getValue().setSeizeTime(0);
            }
            placeData.setLastSeizeCampId(0);
            placeData.setCampId(0);
            placeData.setUpdateTime(System.currentTimeMillis());
            placeData.setUpdateOption();
        }
    }

    public void getPatronsAbilityUserRankByCmd(long userId, long targetServerId) {
        Kuang.KuangUserAbilityRankListReqFromCrossMsg.Builder builder = Kuang.KuangUserAbilityRankListReqFromCrossMsg.newBuilder();
        builder.setOriginUserId(userId);
        builder.setTargetServerId(targetServerId);
        // 到这个服务器去拿数据
        MessageHelper.sendPacket(targetServerId, 0, YanQuMessageUtils.buildMessage(Protocol.S_KUANG_GET_USER_ABILITY_RANK_FROM_CROSS, builder));
    }

    public void getPatronsAbilityUserRankResult(Kuang.CrossKuangUserAbilityRankListRespMsg reqMsg) {
        Kuang.KuangUserAbilityRankListRespMsg.Builder builder = Kuang.KuangUserAbilityRankListRespMsg.newBuilder();
        builder.setRankList(reqMsg.getRankList());
        builder.setMyRank(reqMsg.getMyRank());
        builder.setParam(reqMsg.getParam());
        sendPacket(Protocol.U_KUANG_GET_USER_ABILITY_RANK, builder, reqMsg.getOriginUserId());
    }

    public int getCampRankListByCmd(long userId) {
        Kuang.KuangBattleGetCampRankRespMsg.Builder builder = Kuang.KuangBattleGetCampRankRespMsg.newBuilder();
        builder.setRet(0);
        LinkedList<CrossKuangRank> rankList = campTotalScoreRankModel.getRankList();
        for (CrossKuangRank rank : rankList) {
            builder.addRank(parseKuangCampRankMsg(rank));
        }

        sendPacket(ClientProtocol.U_KUANG_GET_CAMP_RANK_LIST, builder, userId);
        return 0;
    }

    public Kuang.KuangBattleCampRankMsg.Builder parseKuangCampRankMsg(CrossKuangRank rank) {
        int campId = Integer.parseInt(rank.getId());
        Kuang.KuangBattleCampRankMsg.Builder builder = Kuang.KuangBattleCampRankMsg.newBuilder();
        builder.setCampId(campId);
        builder.setValue(rank.getValue());
        return builder;
    }


    /**
     * 获取个人榜单
     */
    public void getUserRankListByCmd(long userId, int type, String param) {
        CrossKuangBattleUserData userData = getUserData(userId);
        long myValue = 0;
        if (userData != null) {
            myValue = userData.calcTotalScore();
        }
        String myId = String.valueOf(userId);
        LinkedList<CrossKuangRank> rankList;
        // TODO
        int maxRank = 9999;
        if (type == 1) {
            // 【个人榜】
            rankList = userScoreRankModel.getRankList();
        } else if (type == 2) {
            // 【阵营内个人榜】
            int campId = Integer.parseInt(param);
            CrossKuangBattleCampData campData = getCampData(campId);
            if (campData == null) {
                return; // 参数错误
            }
            // 组装个榜单
            CrossKuangRankListModel tmpModel = new CrossKuangRankListModel();
            LinkedList<CrossKuangRank> tmpList = new LinkedList<>();
            for (CrossKuangBattleUserData tempUserData : userDataMap.values()) {
                if (tempUserData.getCampId() != campId) {
                    continue;
                }
                long totalScore = tempUserData.calcTotalScore();
                if (totalScore > 0) {
                    tmpList.add(new CrossKuangRank(String.valueOf(tempUserData.getUserId()), totalScore, tempUserData.getUpdateScoreTime()));
                }
            }
            tmpModel.setRankList(tmpList); // 排序
            rankList = tmpModel.getRankList();
        } else {
            return; // 参数错误
        }
        Kuang.KuangBattleGetUserRankRespMsg.Builder builder = Kuang.KuangBattleGetUserRankRespMsg.newBuilder();
        builder.setRet(0);
        int myRank = -1;
        int rankNum = 0;
        for (CrossKuangRank rank : rankList) {
            rankNum++;
            if (rankNum > maxRank) {
                break;
            }
            if (Objects.equals(rank.getId(), myId)) {
                myRank = rankNum;
            }
            builder.addRank(parseKuangUserRankMsg(rank));
        }
        builder.setMyRank(myRank);
        builder.setMyValue(myValue);
        sendPacket(ClientProtocol.U_KUANG_GET_USER_RANK_LIST, builder, userId);
    }

    public Kuang.KuangBattleUserRankMsg.Builder parseKuangUserRankMsg(CrossKuangRank rank) {
        long userId = Long.parseLong(rank.getId());
        UserBaseInfo userBaseInfo = CrossUserMgr.getUserBaseInfo(userId);
        if (userBaseInfo == null) {
            userBaseInfo = new UserBaseInfo();
        }
        int campId = getCampByUserId(userId);

        Kuang.KuangBattleUserRankMsg.Builder builder = Kuang.KuangBattleUserRankMsg.newBuilder();
        builder.setUserId(userId);
        builder.setPlayerBaseData(PlayerBasePb.parsePlayerBaseTempMsg(userBaseInfo));
        builder.setValue(rank.getValue());
        builder.setCampId(campId);
        return builder;
    }

    /**
     * 获取宗门积分记录
     *
     * @param userId 用户id
     * @param campId 宗门id
     * @return
     */
    public int getCampScoreRecordByCmd(long userId, int campId) {
        Kuang.KuangBattleGetCampScoreRecordRespMsg.Builder builder = Kuang.KuangBattleGetCampScoreRecordRespMsg.newBuilder();
        builder.setRet(0);
        for (Map.Entry<Integer, Map<Integer, CrossKuangBattleCampScoreRecord>> entry : crossKuangBattleData.getCampScoreRecordMap().entrySet()) {
            Kuang.KuangBattleCampScoreRecordTemp.Builder temp = Kuang.KuangBattleCampScoreRecordTemp.newBuilder();
            int round = entry.getKey();
            long score = 0;
            CrossKuangBattleCampScoreRecord record = entry.getValue().get(campId);
            if (record != null) {
                score = record.getScore();
            }
            temp.setRound(round);
            temp.setScore(score);
            builder.addScore(temp);
        }
        sendPacket(ClientProtocol.U_KUANG_GET_CAMP_SCORE_RECORD, builder, userId);
        return 0;
    }

    /**
     * 自动发奖
     */
    public void autoRewardTask() {
        if (System.currentTimeMillis() < config.getTimeConfig().getRewardEndTime()) {
            return;
        }
        if (crossKuangBattleData.isRankReward()) {
            return;
        }
        synchronized (lock) {
            if (crossKuangBattleData.isRankReward()) {
                return;
            }
            KuangMatchGroup matchGroup = CrossKuangMgr.getMatchGroup(weekId, groupId);
            if (matchGroup == null) {
                return;
            }
            crossKuangBattleData.setRankReward(true);
            Map<Long, List<CrossKuangRankRewardHelper>> map = new ConcurrentHashMap<>();
            // 发奖励(个人战绩榜单)
            int num = 0;
            for (CrossKuangRank rank : userScoreRankModel.getRankList()) {
                num++;
                // 大于最大排名不发
                if (num > config.getPersonMaxRank()) {
                    break;
                }
                // 判断是否发过奖励
                CrossKuangBattleUserData userData = getUserData(Long.parseLong(rank.getId()));
                if (userData == null) {
                    continue;
                }
                if (userData.isPersonRankReward()) {
                    continue;
                }
                // 记录下标识
                userData.setPersonRankReward(true);
                CrossKuangRankRewardHelper helper = new CrossKuangRankRewardHelper();
                helper.setServerId(userData.getServerId());
                helper.setUserId(userData.getUserId());
                helper.setType(1);
                helper.setRank(num);
                // 获取奖励
                helper.setReward(PropertyHelper.parsePropertyToString(config.getKuangSystemConfig().getPersonRankReward(matchGroup.getOpenDay(), num)));
                List<CrossKuangRankRewardHelper> list = map.getOrDefault(helper.getServerId(), new ArrayList<>());
                list.add(helper);
                map.put(helper.getServerId(), list);
            }
            // 开始发奖励
            for (Map.Entry<Long, List<CrossKuangRankRewardHelper>> entry : map.entrySet()) {
                Kuang.CrossKuangAutoSendRankRewardMsg.Builder builder = Kuang.CrossKuangAutoSendRankRewardMsg.newBuilder();
                Long serverId = entry.getKey();
                for (CrossKuangRankRewardHelper helper : entry.getValue()) {
                    Kuang.CrossKuangAutoSendRankUserTemp.Builder temp = Kuang.CrossKuangAutoSendRankUserTemp.newBuilder();
                    temp.setServerId(helper.getServerId());
                    temp.setUserId(helper.getUserId());
                    temp.setType(helper.getType());
                    temp.setRank(helper.getRank());
                    temp.setReward(helper.getReward());
                    builder.addUser(temp);
                }
                MessageHelper.sendPacket(serverId, 0, YanQuMessageUtils.buildMessage(Protocol.S_KUANG_AUTO_SEND_RANK_REWARD_FROM_CROSS, builder));
            }
        }
    }

    public int getRankRewardByCmd(long userId, int type) {
        CrossKuangBattleUserData userData = getUserData(userId);
        if (userData == null) {
            return GameErrorCode.E_KUANG_BATTLE_USER_NOT_FOUND;
        }
        if (!userData.isEnterBattle()) {
            return GameErrorCode.E_KUANG_NO_ENTER_BATTLE_DONT_REWARD;
        }
        if (System.currentTimeMillis() < config.getTimeConfig().getDay2BattleEndTime()) {
            return GameErrorCode.E_KUANG_BATTLE_NOT_REWARD_TIME;
        }
        KuangMatchGroup matchGroup = CrossKuangMgr.getMatchGroup(weekId, groupId);
        if (matchGroup == null) {
            return GameErrorCode.E_KUANG_SYSTEM_NOT_OPEN;
        }
        // 拿榜单
        String myId;
        LinkedList<CrossKuangRank> rankList;
        if (type == 1) {
            if (userData.isPersonRankReward()) {
                return GameErrorCode.E_KUANG_BATTLE_ALREADY_REWARD;
            }
            rankList = userScoreRankModel.getRankList();
            myId = String.valueOf(userId);
        } else if (type == 2) {
            if (userData.isGroupRankReward()) {
                return GameErrorCode.E_KUANG_BATTLE_ALREADY_REWARD;
            }
            rankList = campTotalScoreRankModel.getRankList();
            myId = String.valueOf(userData.getCampId());
        } else {
            return GameErrorCode.E_KUANG_PARAM_ERROR;
        }
        // 拿榜单排名
        int myRank = -1;
        int num = 0;
        for (CrossKuangRank rank : rankList) {
            num++;
            if (Objects.equals(rank.getId(), myId)) {
                myRank = num;
                break;
            }
        }
        // 获取奖励
        Property reward;
        if (type == 1) {
            if (myRank == -1 || myRank > config.getPersonMaxRank()) {
                return GameErrorCode.E_KUANG_PARAM_ERROR;
            }
            reward = config.getKuangSystemConfig().getPersonRankReward(matchGroup.getOpenDay(), myRank);
            userData.setPersonRankReward(true);
        } else {
            if (myRank == -1 || myRank > config.getGroupMaxRank()) {
                return GameErrorCode.E_KUANG_PARAM_ERROR;
            }
            reward = config.getKuangSystemConfig().getGroupRankReward(matchGroup.getOpenDay(), myRank);
            userData.setGroupRankReward(true);
        }
        // 回游戏服
        Kuang.CrossKuangGetRankRewardRespMsg.Builder builder = Kuang.CrossKuangGetRankRewardRespMsg.newBuilder();
        builder.setRet(0);
        builder.setReward(PropertyHelper.parsePropertyToString(reward));
        sendPacket(Protocol.S_KUANG_GET_RANK_REWARD_FROM_CROSS, builder, userId);
        return 0;
    }

    /**
     * 同步用户属性
     * @param userId
     * @param attributeMap
     */
    public void uploadAttribute(long userId, Map<eKuangAttributeType, Long> attributeMap) {
        CrossKuangBattleUserData userData = userDataMap.containsKey(userId) ? getUserData(userId) : initUserData(userId, attributeMap);
        if (userData != null) {
            // 更新属性
            updateProperty(userData, attributeMap);
            // 更新下战力榜单
            if (userData.getAttributeMap().getOrDefault(eKuangAttributeType.AttributeEnum_Ability, 0L) > 0) {
                CrossKuangRank rank = new CrossKuangRank(String.valueOf(userData.getUserId()), userData.getAttributeMap().getOrDefault(eKuangAttributeType.AttributeEnum_Ability, 0L), userData.getUpdatePropertyTime());
                campUserRankModelMap.putIfAbsent(userData.getCampId(), new CrossKuangRankListModel());
                campUserRankModelMap.get(userData.getCampId()).rankChange(rank);
            }
        }
    }
}
